/* Compiler driver program that can handle many languages.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
/* Nonzero means place this string before uses of /, so that include
and library files can be found in an alternate location. */
+#ifdef TARGET_SYSTEM_ROOT
static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = 0;
+#endif
+
+/* Nonzero means pass the updated target_system_root to the compiler. */
+
+static int target_system_root_changed;
/* Nonzero means write "temp" files in source directory
and use the source file's name in them, and don't delete them. */
static void set_collect_gcc_options PARAMS ((void));
static int do_spec_1 PARAMS ((const char *, int, const char *));
static int do_spec_2 PARAMS ((const char *));
+static void do_option_spec PARAMS ((const char *, const char *));
static void do_self_spec PARAMS ((const char *));
static const char *find_file PARAMS ((const char *));
static int is_directory PARAMS ((const char *, const char *, int));
%w marks the argument containing or following the %w as the
"output file" of this compilation. This puts the argument
into the sequence of arguments that %o will substitute later.
+ %V indicates that this compilation produces no "output file".
%W{...}
like %{...} but mark last argument supplied within
as a file to be deleted on failure.
except that %g, %u, and %U do not currently support additional
SUFFIX characters following %O as they would following, for
example, `.o'.
- %p substitutes the standard macro predefinitions for the
- current target machine. Use this when running cpp.
- %P like %p, but puts `__' before and after the name of each macro.
- (Except macros that already have __.)
- This is for ANSI C.
- %I Substitute a -iprefix option made from GCC_EXEC_PREFIX.
+ %I Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
+ (made from TARGET_SYSTEM_ROOT), and -isystem (made from COMPILER_PATH
+ and -B options) as necessary.
%s current argument is the name of a library or startup file of some sort.
Search for that file in a standard list of directories
and substitute the full name found.
%X Output the accumulated linker options specified by compilations.
%Y Output the accumulated assembler options specified by compilations.
%Z Output the accumulated preprocessor options specified by compilations.
- %v1 Substitute the major version number of GCC.
- (For version 2.5.3, this is 2.)
- %v2 Substitute the minor version number of GCC.
- (For version 2.5.3, this is 5.)
- %v3 Substitute the patch level number of GCC.
- (For version 2.5.3, this is 3.)
%a process ASM_SPEC as a spec.
This allows config.h to specify part of the spec for running as.
%A process ASM_FINAL_SPEC as a spec. A capital A is actually
#define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
#endif
+#ifndef LINK_PIE_SPEC
+#ifdef HAVE_LD_PIE
+#define LINK_PIE_SPEC "%{pie:-pie} "
+#else
+#define LINK_PIE_SPEC "%{pie:} "
+#endif
+#endif
+
/* -u* was put back because both BSD and SysV seem to support it. */
/* %{static:} simply prevents an error message if the target machine
doesn't handle -static. */
#ifndef LINK_COMMAND_SPEC
#define LINK_COMMAND_SPEC "\
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
- %(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t}\
- %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
- %{static:} %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
+ %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
+ %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
+ %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs:-lgcov}\
+ %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
static const char *asm_debug;
static const char *cpp_spec = CPP_SPEC;
-static const char *cpp_predefines = CPP_PREDEFINES;
static const char *cc1_spec = CC1_SPEC;
static const char *cc1plus_spec = CC1PLUS_SPEC;
static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
therefore no dependency entry, confuses make into thinking a .o
file that happens to exist is up-to-date. */
static const char *cpp_unique_options =
-"%{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
%{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
- %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
- %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
+#ifndef OPTION_DEFAULT_SPECS
+#define OPTION_DEFAULT_SPECS { "", "" }
+#endif
+
+struct default_spec
+{
+ const char *name;
+ const char *spec;
+};
+
+static const struct default_spec
+ option_default_specs[] = { OPTION_DEFAULT_SPECS };
+
struct user_specs
{
struct user_specs *next;
static struct user_specs *user_specs_head, *user_specs_tail;
-/* This defines which switch letters take arguments. */
-
-#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
- ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
- || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
- || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
- || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'B' || (CHAR) == 'b')
-
#ifndef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
#endif
-/* This defines which multi-letter switches take arguments. */
-
-#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \
- (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \
- || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \
- || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
- || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
- || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
- || !strcmp (STR, "isystem") || !strcmp (STR, "-param") \
- || !strcmp (STR, "specs") \
- || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ"))
-
#ifndef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
#endif
{".m", "#Objective-C", 0}, {".mi", "#Objective-C", 0},
{".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0},
{".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0},
- {".ii", "#C++", 0},
+ {".CPP", "#C++", 0}, {".ii", "#C++", 0},
{".ads", "#Ada", 0}, {".adb", "#Ada", 0},
{".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0},
{".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
%{!E:%{!M:%{!MM:\
%{traditional|ftraditional:\
%eGNU C no longer supports -traditional without -E}\
- %{save-temps|traditional-cpp:%(trad_capable_cpp) \
- %(cpp_options) %b.i \n\
- cc1 -fpreprocessed %b.i %(cc1_options)}\
- %{!save-temps:%{!traditional-cpp:\
- cc1 %(cpp_unique_options) %(cc1_options)}}\
+ %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+ %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+ cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+ %(cc1_options)}\
+ %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
+ cc1 %(cpp_unique_options) %(cc1_options)}}}\
%{!fsyntax-only:%(invoke_as)}}}}", 0},
{"-",
"%{!E:%e-E required when input is from standard input}\
%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
{".h", "@c-header", 0},
{"@c-header",
- "%{!E:%ecompilation of header file requested} \
- %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
- 0},
+ /* cc1 has an integrated ISO C preprocessor. We should invoke the
+ external preprocessor if -save-temps is given. */
+ "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+ %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+ cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+ %(cc1_options)\
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}\
+ %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
+ cc1 %(cpp_unique_options) %(cc1_options)\
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}}}}}}", 0},
{".i", "@cpp-output", 0},
{"@cpp-output",
"%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
{"--library-directory", "-L", "a"},
{"--machine", "-m", "aj"},
{"--machine-", "-m", "*j"},
+ {"--no-integrated-cpp", "-no-integrated-cpp", 0},
{"--no-line-commands", "-P", 0},
{"--no-precompiled-includes", "-noprecomp", 0},
{"--no-standard-includes", "-nostdinc", 0},
{"--param", "--param", "a"},
{"--pedantic", "-pedantic", 0},
{"--pedantic-errors", "-pedantic-errors", 0},
+ {"--pie", "-pie", 0},
{"--pipe", "-pipe", 0},
{"--prefix", "-B", "a"},
{"--preprocess", "-E", 0},
INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
INIT_STATIC_SPEC ("startfile", &startfile_spec),
INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
- INIT_STATIC_SPEC ("predefines", &cpp_predefines),
INIT_STATIC_SPEC ("cross_compile", &cross_compile),
INIT_STATIC_SPEC ("version", &compiler_version),
INIT_STATIC_SPEC ("multilib", &multilib_select),
PREFIX_PRIORITY_LAST
};
-/* Add an entry for PREFIX in PLIST. The PLIST is kept in assending
+/* Add an entry for PREFIX in PLIST. The PLIST is kept in ascending
order according to PRIORITY. Within each PRIORITY, new entries are
appended.
}
#ifdef ENABLE_VALGRIND_CHECKING
- /* Run the each command through valgrind. To simplifiy prepending the
+ /* Run the each command through valgrind. To simplify prepending the
path to valgrind and the option "-q" (for quiet operation unless
something triggers), we allocate a separate argv array. */
fputs (_(" -o <file> Place the output into <file>\n"), stdout);
fputs (_("\
-x <language> Specify the language of the following input files\n\
- Permissable languages include: c c++ assembler none\n\
+ Permissible languages include: c c++ assembler none\n\
'none' means revert to the default behavior of\n\
guessing the language based on the file's extension\n\
"), stdout);
{
/* translate_options () has turned --version into -fversion. */
printf (_("%s (GCC) %s\n"), programname, version_string);
- fputs (_("Copyright (C) 2002 Free Software Foundation, Inc.\n"),
+ fputs (_("Copyright (C) 2003 Free Software Foundation, Inc.\n"),
stdout);
fputs (_("This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
concat (tooldir_prefix, "lib", dir_separator_str, NULL),
"BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
+ /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
+ then consider it to relocate with the rest of the GCC installation
+ if GCC_EXEC_PREFIX is set.
+ ``make_relative_prefix'' is not compiled for VMS, so don't call it. */
if (target_system_root && gcc_exec_prefix)
{
char *tmp_prefix = make_relative_prefix (argv[0],
standard_bindir_prefix,
target_system_root);
if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
- target_system_root = tmp_prefix;
+ {
+ target_system_root = tmp_prefix;
+ target_system_root_changed = 1;
+ }
}
+#endif
/* More prefixes are enabled in main, after we read the specs file
and determine whether this is cross-compilation or not. */
sans all directory names, and basename_length is the number
of characters starting there excluding the suffix .c or whatever. */
-const char *input_filename;
+static const char *input_filename;
static int input_file_number;
size_t input_filename_length;
static int basename_length;
do_spec_2 (spec)
const char *spec;
{
+ const char *string;
+ int result;
+
clear_args ();
arg_going = 0;
delete_this_arg = 0;
input_from_pipe = 0;
suffix_subst = NULL;
- return do_spec_1 (spec, 0, NULL);
+ result = do_spec_1 (spec, 0, NULL);
+
+ /* End any pending argument. */
+ if (arg_going)
+ {
+ obstack_1grow (&obstack, 0);
+ string = obstack_finish (&obstack);
+ if (this_is_library_file)
+ string = find_file (string);
+ store_arg (string, delete_this_arg, this_is_output_file);
+ if (this_is_output_file)
+ outfiles[input_file_number] = string;
+ arg_going = 0;
+ }
+
+ return result;
}
of the switches/n_switches array. */
static void
+do_option_spec (name, spec)
+ const char *name;
+ const char *spec;
+{
+ unsigned int i, value_count, value_len;
+ const char *p, *q, *value;
+ char *tmp_spec, *tmp_spec_p;
+
+ if (configure_default_options[0].name == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
+ if (strcmp (configure_default_options[i].name, name) == 0)
+ break;
+ if (i == ARRAY_SIZE (configure_default_options))
+ return;
+
+ value = configure_default_options[i].value;
+ value_len = strlen (value);
+
+ /* Compute the size of the final spec. */
+ value_count = 0;
+ p = spec;
+ while ((p = strstr (p, "%(VALUE)")) != NULL)
+ {
+ p ++;
+ value_count ++;
+ }
+
+ /* Replace each %(VALUE) by the specified value. */
+ tmp_spec = alloca (strlen (spec) + 1
+ + value_count * (value_len - strlen ("%(VALUE)")));
+ tmp_spec_p = tmp_spec;
+ q = spec;
+ while ((p = strstr (q, "%(VALUE)")) != NULL)
+ {
+ memcpy (tmp_spec_p, q, p - q);
+ tmp_spec_p = tmp_spec_p + (p - q);
+ memcpy (tmp_spec_p, value, value_len);
+ tmp_spec_p += value_len;
+ q = p + strlen ("%(VALUE)");
+ }
+ strcpy (tmp_spec_p, q);
+
+ do_self_spec (tmp_spec);
+}
+
+/* Process the given spec string and add any new options to the end
+ of the switches/n_switches array. */
+
+static void
do_self_spec (spec)
const char *spec;
{
for (t = temp_names; t; t = t->next)
if (t->length == suffix_length
&& strncmp (t->suffix, suffix, suffix_length) == 0
- && t->unique == (c == 'u' || c == 'j'))
+ && t->unique == (c == 'u' || c == 'U' || c == 'j'))
break;
/* Make a new association if needed. %u and %j
}
else
t->suffix = save_string (suffix, suffix_length);
- t->unique = (c == 'u' || c == 'j');
+ t->unique = (c == 'u' || c == 'U' || c == 'j');
temp_filename = make_temp_file (t->suffix);
temp_filename_length = strlen (temp_filename);
t->filename = temp_filename;
do_spec_1 (" ", 0, NULL);
}
+ if (target_system_root_changed)
+ {
+ do_spec_1 ("-isysroot", 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (target_system_root, 1, NULL);
+ do_spec_1 (" ", 0, NULL);
+ }
+
for (; pl; pl = pl->next)
{
do_spec_1 ("-isystem", 1, NULL);
this_is_library_file = 1;
break;
+ case 'V':
+ outfiles[input_file_number] = NULL;
+ break;
+
case 'w':
this_is_output_file = 1;
break;
p = handle_braces (p + 1);
if (p == 0)
return -1;
+ /* End any pending argument. */
+ if (arg_going)
+ {
+ obstack_1grow (&obstack, 0);
+ string = obstack_finish (&obstack);
+ if (this_is_library_file)
+ string = find_file (string);
+ store_arg (string, delete_this_arg, this_is_output_file);
+ if (this_is_output_file)
+ outfiles[input_file_number] = string;
+ arg_going = 0;
+ }
/* If any args were output, mark the last one for deletion
on failure. */
if (argbuf_index != cur_index)
}
break;
- case 'p':
- {
- char *x = (char *) alloca (strlen (cpp_predefines) + 1);
- char *buf = x;
- const char *y;
-
- /* Copy all of the -D options in CPP_PREDEFINES into BUF. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-D", 2))
- /* Copy the whole option. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy other options. */
- else
- y++;
- }
-
- *x = 0;
-
- value = do_spec_1 (buf, 0, NULL);
- if (value != 0)
- return value;
- }
- break;
-
- case 'P':
- {
- char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
- char *buf = x;
- const char *y;
-
- /* Copy all of CPP_PREDEFINES into BUF,
- but force them all into the reserved name space if they
- aren't already there. The reserved name space is all
- identifiers beginning with two underscores or with one
- underscore and a capital letter. We do the forcing by
- adding up to two underscores to the beginning and end
- of each symbol. e.g. mips, _mips, mips_, and _mips_ all
- become __mips__. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-D", 2))
- {
- int flag = 0;
-
- *x++ = *y++;
- *x++ = *y++;
-
- if (*y != '_'
- || (*(y + 1) != '_'
- && ! ISUPPER ((unsigned char) *(y + 1))))
- {
- /* Stick __ at front of macro name. */
- if (*y != '_')
- *x++ = '_';
- *x++ = '_';
- /* Arrange to stick __ at the end as well. */
- flag = 1;
- }
-
- /* Copy the macro name. */
- while (*y && *y != '=' && *y != ' ' && *y != '\t')
- *x++ = *y++;
-
- if (flag)
- {
- if (x[-1] != '_')
- {
- if (x[-2] != '_')
- *x++ = '_';
- *x++ = '_';
- }
- }
-
- /* Copy the value given, if any. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- }
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy -A options */
- else
- y++;
- }
- *x++ = ' ';
-
- /* Copy all of CPP_PREDEFINES into BUF,
- but put __ after every -D. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-D", 2))
- {
- y += 2;
-
- if (*y != '_'
- || (*(y + 1) != '_'
- && ! ISUPPER ((unsigned char) *(y + 1))))
- {
- /* Stick -D__ at front of macro name. */
- *x++ = '-';
- *x++ = 'D';
- if (*y != '_')
- *x++ = '_';
- *x++ = '_';
-
- /* Copy the macro name. */
- while (*y && *y != '=' && *y != ' ' && *y != '\t')
- *x++ = *y++;
-
- /* Copy the value given, if any. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- }
- else
- {
- /* Do not copy this macro - we have just done it before */
- while (*y && *y != ' ' && *y != '\t')
- y++;
- }
- }
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy -A options. */
- else
- y++;
- }
- *x++ = ' ';
-
- /* Copy all of the -A options in CPP_PREDEFINES into BUF. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-A", 2))
- /* Copy the whole option. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy other options. */
- else
- y++;
- }
-
- *x = 0;
-
- value = do_spec_1 (buf, 0, NULL);
- if (value != 0)
- return value;
- }
- break;
-
case 'R':
/* We assume there is a directory
separator at the end of this string. */
}
break;
- case 'v':
- {
- int c1 = *p++; /* Select first or second version number. */
- const char *v = compiler_version;
- const char *q;
- static const char zeroc = '0';
-
- /* The format of the version string is
- ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
-
- /* Ignore leading non-digits. i.e. "foo-" in "foo-2.7.2". */
- while (! ISDIGIT (*v))
- v++;
- if (v > compiler_version && v[-1] != '-')
- abort ();
-
- /* If desired, advance to second version number. */
- if (c1 >= '2')
- {
- /* Set V after the first period. */
- while (ISDIGIT (*v))
- v++;
- if (*v != '.')
- abort ();
- v++;
- }
-
- /* If desired, advance to third version number.
- But don't complain if it's not present */
- if (c1 == '3')
- {
- /* Set V after the second period. */
- while (ISDIGIT (*v))
- v++;
- if ((*v != 0) && (*v != ' ') && (*v != '.') && (*v != '-'))
- abort ();
- if (*v != 0)
- v++;
- }
-
- /* Set Q at the next period or at the end. */
- q = v;
- while (ISDIGIT (*q))
- q++;
- if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
- abort ();
-
- if (q > v)
- /* Put that part into the command. */
- obstack_grow (&obstack, v, q - v);
- else
- /* Default to "0" */
- obstack_grow (&obstack, &zeroc, 1);
- arg_going = 1;
- }
- break;
-
default:
error ("spec failure: unrecognized spec option '%c'", c);
break;
size_t i;
int value;
int linker_was_run = 0;
+ int num_linker_inputs = 0;
char *explicit_link_files;
char *specs_file;
const char *p;
process_command (argc, argv);
- /* Process DRIVER_SELF_SPECS, adding any new options to the end
- of the command line. */
-
- for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
- do_self_spec (driver_self_specs[i]);
-
/* Initialize the vector of specs to just the default.
This means one element containing 0s, as a terminator. */
if (access (specs_file, R_OK) == 0)
read_specs (specs_file, TRUE);
+ /* Process any configure-time defaults specified for the command line
+ options, via OPTION_DEFAULT_SPECS. */
+ for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
+ do_option_spec (option_default_specs[i].name,
+ option_default_specs[i].spec);
+
+ /* Process DRIVER_SELF_SPECS, adding any new options to the end
+ of the command line. */
+
+ for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
+ do_self_spec (driver_self_specs[i]);
+
/* If not cross-compiling, look for executables in the standard
places. */
if (*cross_compile == '0')
error_count++;
}
+ /* Determine if there are any linker input files. */
+ num_linker_inputs = 0;
+ for (i = 0; (int) i < n_infiles; i++)
+ if (explicit_link_files[i] || outfiles[i] != NULL)
+ num_linker_inputs++;
+
/* Run ld to link all the compiler output files. */
- if (error_count == 0)
+ if (num_linker_inputs > 0 && error_count == 0)
{
int tmp = execution_count;
/* Output an error message and exit */
void
-fatal VPARAMS ((const char *msgid, ...))
+fatal (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+
+ va_start (ap, msgid);
fprintf (stderr, "%s: ", programname);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
fprintf (stderr, "\n");
delete_temp_files ();
exit (1);
}
void
-error VPARAMS ((const char *msgid, ...))
+error (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
+ va_list ap;
+
+ va_start (ap, msgid);
fprintf (stderr, "%s: ", programname);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
fprintf (stderr, "\n");
}
static void
-notice VPARAMS ((const char *msgid, ...))
+notice (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
+ va_list ap;
+
+ va_start (ap, msgid);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
\f
static inline void
switches[i].validated = 1;
}
- p++;
- if (p[-1] == '|' || p[-1] == '&')
+ if (*p) p++;
+ if (*p && (p[-1] == '|' || p[-1] == '&'))
goto next_member;
- if (p[-1] == ':')
+ if (*p && p[-1] == ':')
{
while (*p && *p != ';' && *p != '}')
{
else if (p[0] == 'W' && p[1] == '{')
p = validate_switches (p+2);
}
- p++;
+ else
+ p++;
}
- p++;
- if (p[-1] == ';')
+ if (*p) p++;
+ if (*p && p[-1] == ';')
goto next_member;
}