/* Compiler driver program that can handle many languages.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "multilib.h" /* before tm.h */
#include "tm.h"
#include <signal.h>
#if ! defined( SIGCHLD ) && defined( SIGCLD )
#include <sys/resource.h>
#endif
#if defined (HAVE_DECL_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
-extern int getrusage PARAMS ((int, struct rusage *));
+extern int getrusage (int, struct rusage *);
#endif
/* By default there is no special suffix for target executables. */
#define TARGET_OBJECT_SUFFIX ".o"
#endif
-#ifndef VMS
-/* FIXME: the location independence code for VMS is hairier than this,
- and hasn't been written. */
-#ifndef DIR_UP
-#define DIR_UP ".."
-#endif /* DIR_UP */
-#endif /* VMS */
-
static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
/* Most every one is fine with LIBRARY_PATH. For some, it conflicts. */
/* 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 append this string to target_system_root. */
+
+static const char *target_sysroot_suffix = 0;
+
+/* Nonzero means append this string to target_system_root for headers. */
+
+static const char *target_sysroot_hdrs_suffix = 0;
+
/* Nonzero means write "temp" files in source directory
and use the source file's name in them, and don't delete them. */
static int save_temps_flag;
+/* Nonzero means pass multiple source files to the compiler at one time. */
+
+static int combine_flag = 0;
+
/* Nonzero means use pipes to communicate between subprocesses.
Overridden by either of the above two flags. */
/* Forward declaration for prototypes. */
struct path_prefix;
-
-static void init_spec PARAMS ((void));
-static void store_arg PARAMS ((const char *, int, int));
-static char *load_specs PARAMS ((const char *));
-static void read_specs PARAMS ((const char *, int));
-static void set_spec PARAMS ((const char *, const char *));
-static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const char *));
-static char *build_search_list PARAMS ((struct path_prefix *, const char *, int));
-static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *));
-static int access_check PARAMS ((const char *, int));
-static char *find_a_file PARAMS ((struct path_prefix *, const char *,
- int, int));
-static void add_prefix PARAMS ((struct path_prefix *, const char *,
- const char *, int, int, int *, int));
-static void add_sysrooted_prefix PARAMS ((struct path_prefix *, const char *,
- const char *, int, int, int *, int));
-static void translate_options PARAMS ((int *, const char *const **));
-static char *skip_whitespace PARAMS ((char *));
-static void delete_if_ordinary PARAMS ((const char *));
-static void delete_temp_files PARAMS ((void));
-static void delete_failure_queue PARAMS ((void));
-static void clear_failure_queue PARAMS ((void));
-static int check_live_switch PARAMS ((int, int));
-static const char *handle_braces PARAMS ((const char *));
-static inline bool input_suffix_matches PARAMS ((const char *,
- const char *));
-static inline bool switch_matches PARAMS ((const char *,
- const char *, int));
-static inline void mark_matching_switches PARAMS ((const char *,
- const char *, int));
-static inline void process_marked_switches PARAMS ((void));
-static const char *process_brace_body PARAMS ((const char *, const char *,
- const char *, int, int));
-static const struct spec_function *lookup_spec_function PARAMS ((const char *));
-static const char *eval_spec_function PARAMS ((const char *, const char *));
-static const char *handle_spec_function PARAMS ((const char *));
-static char *save_string PARAMS ((const char *, int));
-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_self_spec PARAMS ((const char *));
-static const char *find_file PARAMS ((const char *));
-static int is_directory PARAMS ((const char *, const char *, int));
-static const char *validate_switches PARAMS ((const char *));
-static void validate_all_switches PARAMS ((void));
-static inline void validate_switches_from_spec PARAMS ((const char *));
-static void give_switch PARAMS ((int, int));
-static int used_arg PARAMS ((const char *, int));
-static int default_arg PARAMS ((const char *, int));
-static void set_multilib_dir PARAMS ((void));
-static void print_multilib_info PARAMS ((void));
-static void perror_with_name PARAMS ((const char *));
-static void pfatal_pexecute PARAMS ((const char *, const char *))
- ATTRIBUTE_NORETURN;
-static void notice PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1;
-static void display_help PARAMS ((void));
-static void add_preprocessor_option PARAMS ((const char *, int));
-static void add_assembler_option PARAMS ((const char *, int));
-static void add_linker_option PARAMS ((const char *, int));
-static void process_command PARAMS ((int, const char *const *));
-static int execute PARAMS ((void));
-static void alloc_args PARAMS ((void));
-static void clear_args PARAMS ((void));
-static void fatal_error PARAMS ((int));
-#ifdef ENABLE_SHARED_LIBGCC
-static void init_gcc_specs PARAMS ((struct obstack *,
- const char *, const char *,
- const char *));
+struct prefix_list;
+
+static void init_spec (void);
+static void store_arg (const char *, int, int);
+static char *load_specs (const char *);
+static void read_specs (const char *, int);
+static void set_spec (const char *, const char *);
+static struct compiler *lookup_compiler (const char *, size_t, const char *);
+static char *build_search_list (struct path_prefix *, const char *, int);
+static void putenv_from_prefixes (struct path_prefix *, const char *);
+static int access_check (const char *, int);
+static char *find_a_file (struct path_prefix *, const char *, int, int);
+static void add_prefix (struct path_prefix *, const char *, const char *,
+ int, int, int);
+static void add_sysrooted_prefix (struct path_prefix *, const char *,
+ const char *, int, int, int);
+static void translate_options (int *, const char *const **);
+static char *skip_whitespace (char *);
+static void delete_if_ordinary (const char *);
+static void delete_temp_files (void);
+static void delete_failure_queue (void);
+static void clear_failure_queue (void);
+static int check_live_switch (int, int);
+static const char *handle_braces (const char *);
+static inline bool input_suffix_matches (const char *, const char *);
+static inline bool switch_matches (const char *, const char *, int);
+static inline void mark_matching_switches (const char *, const char *, int);
+static inline void process_marked_switches (void);
+static const char *process_brace_body (const char *, const char *, const char *, int, int);
+static const struct spec_function *lookup_spec_function (const char *);
+static const char *eval_spec_function (const char *, const char *);
+static const char *handle_spec_function (const char *);
+static char *save_string (const char *, int);
+static void set_collect_gcc_options (void);
+static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *);
+static int do_spec_1 (const char *, int, const char *);
+static int do_spec_2 (const char *);
+static void do_option_spec (const char *, const char *);
+static void do_self_spec (const char *);
+static const char *find_file (const char *);
+static int is_directory (const char *, const char *, int);
+static const char *validate_switches (const char *);
+static void validate_all_switches (void);
+static inline void validate_switches_from_spec (const char *);
+static void give_switch (int, int);
+static int used_arg (const char *, int);
+static int default_arg (const char *, int);
+static void set_multilib_dir (void);
+static void print_multilib_info (void);
+static void perror_with_name (const char *);
+static void pfatal_pexecute (const char *, const char *) ATTRIBUTE_NORETURN;
+static void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
+static void display_help (void);
+static void add_preprocessor_option (const char *, int);
+static void add_assembler_option (const char *, int);
+static void add_linker_option (const char *, int);
+static void process_command (int, const char **);
+static int execute (void);
+static void alloc_args (void);
+static void clear_args (void);
+static void fatal_error (int);
+#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
+static void init_gcc_specs (struct obstack *, const char *, const char *,
+ const char *);
#endif
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
-static const char *convert_filename PARAMS ((const char *, int, int));
+static const char *convert_filename (const char *, int, int);
#endif
-static const char *if_exists_spec_function PARAMS ((int, const char **));
-static const char *if_exists_else_spec_function PARAMS ((int, const char **));
+static const char *if_exists_spec_function (int, const char **);
+static const char *if_exists_else_spec_function (int, const char **);
+static const char *replace_outfile_spec_function (int, const char **);
\f
/* The Specs Language
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 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.
%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
name starts with `o'. %{o*} would substitute this text,
including the space; thus, two arguments would be generated.
%{S*&T*} likewise, but preserve order of S and T options (the order
- of S and T in the spec is not significant). Can be any number
- of ampersand-separated variables; for each the wild card is
- optional. Useful for CPP as %{D*&U*&A*}.
+ of S and T in the spec is not significant). Can be any number
+ of ampersand-separated variables; for each the wild card is
+ optional. Useful for CPP as %{D*&U*&A*}.
%{S:X} substitutes X, if the -S switch was given to CC.
%{!S:X} substitutes X, if the -S switch was NOT given to CC.
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif
+/* mudflap specs */
+#ifndef MFWRAP_SPEC
+/* XXX: valid only for GNU ld */
+/* XXX: should exactly match hooks provided by libmudflap.a */
+#define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
+ --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
+ --wrap=mmap --wrap=munmap --wrap=alloca\
+} %{fmudflapth: --wrap=pthread_create --wrap=pthread_join --wrap=pthread_exit\
+}} %{fmudflap|fmudflapth: --wrap=main}"
+#endif
+#ifndef MFLIB_SPEC
+#define MFLIB_SPEC "%{fmudflap|fmudflapth: -export-dynamic}"
+#endif
+
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
-#if defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
+#if defined(REAL_LIBGCC_SPEC)
+#define LIBGCC_SPEC REAL_LIBGCC_SPEC
+#elif defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
/* Have gcc do the search for libgcc.a. */
#define LIBGCC_SPEC "libgcc.a%s"
#else
#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 %{fprofile-arcs:-lgcov}\
+ %(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*} %(mfwrap) %(link_libgcc) %o %(mflib)\
+ %{fprofile-arcs|fprofile-generate:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
# define STARTFILE_PREFIX_SPEC ""
#endif
+#ifndef SYSROOT_SUFFIX_SPEC
+# define SYSROOT_SUFFIX_SPEC ""
+#endif
+
+#ifndef SYSROOT_HEADERS_SUFFIX_SPEC
+# define SYSROOT_HEADERS_SUFFIX_SPEC ""
+#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;
static const char *asm_final_spec = ASM_FINAL_SPEC;
static const char *link_spec = LINK_SPEC;
static const char *lib_spec = LIB_SPEC;
+static const char *mfwrap_spec = MFWRAP_SPEC;
+static const char *mflib_spec = MFLIB_SPEC;
static const char *libgcc_spec = LIBGCC_SPEC;
static const char *endfile_spec = ENDFILE_SPEC;
static const char *startfile_spec = STARTFILE_SPEC;
static const char *link_command_spec = LINK_COMMAND_SPEC;
static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
+static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
+static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
/* Standard options to cpp, cc1, and as, to reduce duplication in specs.
There should be no need to override these in target dependent files,
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}}\
- %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
+"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
+ %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{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\
+ %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
+ %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
options used to set target flags. Those special target flags settings may
in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options =
-"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{O*} %{undef}";
+"%(cpp_unique_options) %1 %{m*} %{std*&ansi} %{W*&pedantic*} %{w} %{f*}\
+ %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}\
+ %{save-temps:-fpch-preprocess}";
/* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */
static const char *cc1_options =
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
- -auxbase%{c|S:%{o*:-strip %*}%{!o*: %b}}%{!c:%{!S: %b}}\
- %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi}\
%{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
%{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
- %{fsyntax-only:-o %j} %{-param*}";
+ %{fsyntax-only:-o %j} %{-param*}\
+ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}";
static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
static const char *multilib_matches;
static const char *multilib_defaults;
static const char *multilib_exclusions;
-#include "multilib.h"
/* Check whether a particular argument is a default argument. */
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
const char *cpp_spec; /* If non-NULL, substitute this spec
for `%C', rather than the usual
cpp_spec. */
+ const int combinable; /* If nonzero, compiler can deal with
+ multiple source files at once (IMA). */
+ const int needs_preprocessing; /* If nonzero, source files need to
+ be run through a preprocessor. */
};
/* Pointer to a vector of `struct compiler' that gives the spec for
were not present when we built the driver, we will hit these copies
and be given a more meaningful error than "file not used since
linking is not done". */
- {".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},
- {".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},
- {".r", "#Ratfor", 0},
- {".p", "#Pascal", 0}, {".pas", "#Pascal", 0},
- {".java", "#Java", 0}, {".class", "#Java", 0},
- {".zip", "#Java", 0}, {".jar", "#Java", 0},
+ {".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0},
+ {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
+ {".mii", "#Objective-C++", 0, 0, 0},
+ {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
+ {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
+ {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
+ {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
+ {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
+ {".f", "#Fortran", 0, 0, 0}, {".for", "#Fortran", 0, 0, 0},
+ {".F", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
+ {".FPP", "#Fortran", 0, 0, 0},
+ {".f90", "#Fortran 95", 0, 0, 0}, {".f95", "#Fortran 95", 0, 0, 0},
+ {".fpp", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
+ {".FOR", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
+ {".r", "#Ratfor", 0, 0, 0},
+ {".p", "#Pascal", 0, 0, 0}, {".pas", "#Pascal", 0, 0, 0},
+ {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0},
+ {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0},
/* Next come the entries for C. */
- {".c", "@c", 0},
+ {".c", "@c", 0, 1, 1},
{"@c",
/* cc1 has an integrated ISO C preprocessor. We should invoke the
external preprocessor if -save-temps is given. */
%{!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:\
+ %{!combine:\
+ %{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)}} \
+ %{combine:\
+ %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+ %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i}}\
+ %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
cc1 %(cpp_unique_options) %(cc1_options)}}\
- %{!fsyntax-only:%(invoke_as)}}}}", 0},
+ %{!fsyntax-only:%(invoke_as)}}}}}}", 0, 1, 1},
{"-",
"%{!E:%e-E required when input is from standard input}\
- %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
- {".h", "@c-header", 0},
+ %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
+ {".h", "@c-header", 0, 0, 0},
{"@c-header",
/* 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:%(trad_capable_cpp) \
- %(cpp_options) %b.i \n\
- cc1 -fpreprocessed %b.i %(cc1_options)\
- -o %g.s %{!o*:--output-pch=%i.pch}\
+ %{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:\
+ %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
cc1 %(cpp_unique_options) %(cc1_options)\
- -o %g.s %{!o*:--output-pch=%i.pch}\
- %W{o*:--output-pch=%*}%V}}}}}", 0},
- {".i", "@cpp-output", 0},
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}}}}}}", 0, 0, 0},
+ {".i", "@cpp-output", 0, 1, 0},
{"@cpp-output",
- "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
- {".s", "@assembler", 0},
+ "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
+ {".s", "@assembler", 0, 1, 0},
{"@assembler",
- "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0},
- {".S", "@assembler-with-cpp", 0},
+ "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
+ {".S", "@assembler-with-cpp", 0, 1, 0},
{"@assembler-with-cpp",
#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
"%(trad_capable_cpp) -lang-asm %(cpp_options)\
%{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
as %(asm_debug) %(asm_options) %m.s %A }}}}"
#endif
- , 0},
-
+ , 0, 1, 0},
+
#include "specs.h"
- /* Mark end of table */
- {0, 0, 0}
+ /* Mark end of table. */
+ {0, 0, 0, 0, 0}
};
/* Number of elements in default_compilers, not counting the terminator. */
{"--classpath", "-fclasspath=", "aj"},
{"--bootclasspath", "-fbootclasspath=", "aj"},
{"--CLASSPATH", "-fclasspath=", "aj"},
+ {"--combine", "-combine", 0},
{"--comments", "-C", 0},
{"--comments-in-macros", "-CC", 0},
{"--compile", "-c", 0},
{"--dependencies", "-M", 0},
{"--dump", "-d", "a"},
{"--dumpbase", "-dumpbase", "a"},
+ {"--encoding", "-fencoding=", "aj"},
{"--entry", "-e", 0},
{"--extra-warnings", "-W", 0},
+ {"--extdirs", "-fextdirs=", "aj"},
{"--for-assembler", "-Wa", "a"},
{"--for-linker", "-Xlinker", "a"},
{"--force-link", "-u", "a"},
{"--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},
{"--static", "-static", 0},
{"--std", "-std=", "aj"},
{"--symbolic", "-symbolic", 0},
- {"--target", "-b", "a"},
{"--time", "-time", 0},
{"--trace-includes", "-H", 0},
{"--traditional", "-traditional", 0},
{"--traditional-cpp", "-traditional-cpp", 0},
{"--trigraphs", "-trigraphs", 0},
{"--undefine-macro", "-U", "aj"},
- {"--use-version", "-V", "a"},
{"--user-dependencies", "-MM", 0},
{"--verbose", "-v", 0},
{"--warn-", "-W", "*j"},
and store its length in *ARGVC. */
static void
-translate_options (argcp, argvp)
- int *argcp;
- const char *const **argvp;
+translate_options (int *argcp, const char *const **argvp)
{
int i;
int argc = *argcp;
const char *const *argv = *argvp;
int newvsize = (argc + 2) * 2 * sizeof (const char *);
- const char **newv =
- (const char **) xmalloc (newvsize);
+ const char **newv = xmalloc (newvsize);
int newindex = 0;
i = 0;
}
newvsize += spaces * sizeof (const char *);
- newv = (const char **) xrealloc (newv, newvsize);
+ newv = xrealloc (newv, newvsize);
sp = target_option_translations[tott_idx].replacements;
np = xstrdup (sp);
else if (strchr (arginfo, '*') != 0)
{
- error ("incomplete `%s' option", option_map[j].name);
+ error ("incomplete '%s' option", option_map[j].name);
break;
}
{
if (i + 1 == argc)
{
- error ("missing argument to `%s' option",
+ error ("missing argument to '%s' option",
option_map[j].name);
break;
}
else if (strchr (arginfo, 'o') == 0)
{
if (arg != 0)
- error ("extraneous argument to `%s' option",
+ error ("extraneous argument to '%s' option",
option_map[j].name);
arg = 0;
}
}
\f
static char *
-skip_whitespace (p)
- char *p;
+skip_whitespace (char *p)
{
while (1)
{
struct prefix_list *next; /* Next in linked list. */
int require_machine_suffix; /* Don't use without machine_suffix. */
/* 2 means try both machine_suffix and just_machine_suffix. */
- int *used_flag_ptr; /* 1 if a file was found with this prefix. */
int priority; /* Sort key - priority within list. */
int os_multilib; /* 1 if OS multilib scheme should be used,
0 for GCC multilib scheme. */
static const char *gcc_exec_prefix;
+/* Adjusted value of standard_libexec_prefix. */
+
+static const char *gcc_libexec_prefix;
+
/* Default prefixes to attach to command names. */
+#ifndef STANDARD_STARTFILE_PREFIX_1
+#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
+#endif
+#ifndef STANDARD_STARTFILE_PREFIX_2
+#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
+#endif
+
#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
#define MD_STARTFILE_PREFIX_1 ""
#endif
-/* Supply defaults for the standard prefixes. */
-
-#ifndef STANDARD_EXEC_PREFIX
-#define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
-#endif
-#ifndef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
-#endif
-#ifndef TOOLDIR_BASE_PREFIX
-#define TOOLDIR_BASE_PREFIX "/usr/local/"
-#endif
-#ifndef STANDARD_BINDIR_PREFIX
-#define STANDARD_BINDIR_PREFIX "/usr/local/bin"
-#endif
-
static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
-static const char *const standard_exec_prefix_1 = "/usr/lib/gcc/";
+static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
+static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
static const char *md_exec_prefix = MD_EXEC_PREFIX;
static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
-static const char *const standard_startfile_prefix_1 = "/lib/";
-static const char *const standard_startfile_prefix_2 = "/usr/lib/";
+static const char *const standard_startfile_prefix_1
+ = STANDARD_STARTFILE_PREFIX_1;
+static const char *const standard_startfile_prefix_2
+ = STANDARD_STARTFILE_PREFIX_2;
static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
static const char *tooldir_prefix;
static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
+static const char *standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
+
/* Subdirectory to use for locating libraries. Set by
set_multilib_dir based on the compilation options. */
INIT_STATIC_SPEC ("endfile", &endfile_spec),
INIT_STATIC_SPEC ("link", &link_spec),
INIT_STATIC_SPEC ("lib", &lib_spec),
+ INIT_STATIC_SPEC ("mfwrap", &mfwrap_spec),
+ INIT_STATIC_SPEC ("mflib", &mflib_spec),
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),
INIT_STATIC_SPEC ("md_startfile_prefix", &md_startfile_prefix),
INIT_STATIC_SPEC ("md_startfile_prefix_1", &md_startfile_prefix_1),
INIT_STATIC_SPEC ("startfile_prefix_spec", &startfile_prefix_spec),
+ INIT_STATIC_SPEC ("sysroot_suffix_spec", &sysroot_suffix_spec),
+ INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec", &sysroot_hdrs_suffix_spec),
};
#ifdef EXTRA_SPECS /* additional specs needed */
{
{ "if-exists", if_exists_spec_function },
{ "if-exists-else", if_exists_else_spec_function },
+ { "replace-outfile", replace_outfile_spec_function },
{ 0, 0 }
};
/* Add appropriate libgcc specs to OBSTACK, taking into account
various permutations of -shared-libgcc, -shared, and such. */
-#ifdef ENABLE_SHARED_LIBGCC
+#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
+
+#ifndef USE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 0
+#endif
+
static void
-init_gcc_specs (obstack, shared_name, static_name, eh_name)
- struct obstack *obstack;
- const char *shared_name;
- const char *static_name;
- const char *eh_name;
+init_gcc_specs (struct obstack *obstack, const char *shared_name,
+ const char *static_name, const char *eh_name)
{
char *buf;
buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
"}%{!static:%{!static-libgcc:",
+#if USE_LD_AS_NEEDED
+ "%{!shared-libgcc:", static_name,
+ " --as-needed ", shared_name, " --no-as-needed}"
+ "%{shared-libgcc:", shared_name, "%{!shared: ", static_name,
+ "}",
+#else
"%{!shared:%{!shared-libgcc:", static_name, " ",
eh_name, "}%{shared-libgcc:", shared_name, " ",
static_name, "}}%{shared:",
#else
shared_name,
#endif
+#endif
"}}}", NULL);
obstack_grow (obstack, buf, strlen (buf));
/* Initialize the specs lookup routines. */
static void
-init_spec ()
+init_spec (void)
{
struct spec_list *next = (struct spec_list *) 0;
struct spec_list *sl = (struct spec_list *) 0;
notice ("Using built-in specs.\n");
#ifdef EXTRA_SPECS
- extra_specs = (struct spec_list *)
- xcalloc (sizeof (struct spec_list), ARRAY_SIZE (extra_specs_1));
+ extra_specs = xcalloc (sizeof (struct spec_list),
+ ARRAY_SIZE (extra_specs_1));
for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
{
next = sl;
}
-#ifdef ENABLE_SHARED_LIBGCC
+#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
/* ??? If neither -shared-libgcc nor --static-libgcc was
seen, then we should be making an educated guess. Some proposed
heuristics for ELF include:
#endif
,
"-lgcc",
- "-lgcc_eh");
+ "-lgcc_eh"
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
+#endif
+ );
+
p += 5;
in_sep = 0;
}
#endif
,
"libgcc.a%s",
- "libgcc_eh.a%s");
+ "libgcc_eh.a%s"
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
+#endif
+ );
p += 10;
in_sep = 0;
}
current spec. */
static void
-set_spec (name, spec)
- const char *name;
- const char *spec;
+set_spec (const char *name, const char *spec)
{
struct spec_list *sl;
const char *old_spec;
if (!sl)
{
/* Not found - make it. */
- sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
+ sl = xmalloc (sizeof (struct spec_list));
sl->name = xstrdup (name);
sl->name_len = name_len;
sl->ptr_spec = &sl->ptr;
/* Free the old spec. */
if (old_spec && sl->alloc_p)
- free ((PTR) old_spec);
+ free ((void *) old_spec);
sl->alloc_p = 1;
}
static int argbuf_index;
+/* Position in the argbuf array containing the name of the output file
+ (the value associated with the "-o" flag). */
+
+static int have_o_argbuf_index = 0;
+
/* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
temp file. If the HOST_BIT_BUCKET is used for %j, no entry is made for
it here. */
/* Allocate the argument vector. */
static void
-alloc_args ()
+alloc_args (void)
{
argbuf_length = 10;
- argbuf = (const char **) xmalloc (argbuf_length * sizeof (const char *));
+ argbuf = xmalloc (argbuf_length * sizeof (const char *));
}
/* Clear out the vector of arguments (after a command is executed). */
static void
-clear_args ()
+clear_args (void)
{
argbuf_index = 0;
}
and the file should be deleted if this compilation fails. */
static void
-store_arg (arg, delete_always, delete_failure)
- const char *arg;
- int delete_always, delete_failure;
+store_arg (const char *arg, int delete_always, int delete_failure)
{
if (argbuf_index + 1 == argbuf_length)
- argbuf
- = (const char **) xrealloc (argbuf,
- (argbuf_length *= 2) * sizeof (const char *));
+ argbuf = xrealloc (argbuf, (argbuf_length *= 2) * sizeof (const char *));
argbuf[argbuf_index++] = arg;
argbuf[argbuf_index] = 0;
+ if (strcmp (arg, "-o") == 0)
+ have_o_argbuf_index = argbuf_index;
if (delete_always || delete_failure)
record_temp_file (arg, delete_always, delete_failure);
}
a single \n. */
static char *
-load_specs (filename)
- const char *filename;
+load_specs (const char *filename)
{
int desc;
int readlen;
Anything invalid in the file is a fatal error. */
static void
-read_specs (filename, main_p)
- const char *filename;
- int main_p;
+read_specs (const char *filename, int main_p)
{
char *buffer;
char *p;
set_spec (p2, *(sl->ptr_spec));
if (sl->alloc_p)
- free ((PTR) *(sl->ptr_spec));
+ free ((void *) *(sl->ptr_spec));
*(sl->ptr_spec) = "";
sl->alloc_p = 0;
{
/* Add this pair to the vector. */
compilers
- = ((struct compiler *)
- xrealloc (compilers,
- (n_compilers + 2) * sizeof (struct compiler)));
+ = xrealloc (compilers,
+ (n_compilers + 2) * sizeof (struct compiler));
compilers[n_compilers].suffix = suffix;
compilers[n_compilers].spec = spec;
otherwise delete it in any case. */
void
-record_temp_file (filename, always_delete, fail_delete)
- const char *filename;
- int always_delete;
- int fail_delete;
+record_temp_file (const char *filename, int always_delete, int fail_delete)
{
char *const name = xstrdup (filename);
if (! strcmp (name, temp->name))
goto already1;
- temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
+ temp = xmalloc (sizeof (struct temp_file));
temp->next = always_delete_queue;
temp->name = name;
always_delete_queue = temp;
if (! strcmp (name, temp->name))
goto already2;
- temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
+ temp = xmalloc (sizeof (struct temp_file));
temp->next = failure_delete_queue;
temp->name = name;
failure_delete_queue = temp;
/* Delete all the temporary files whose names we previously recorded. */
+#ifndef DELETE_IF_ORDINARY
+#define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG) \
+do \
+ { \
+ if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode)) \
+ if (unlink (NAME) < 0) \
+ if (VERBOSE_FLAG) \
+ perror_with_name (NAME); \
+ } while (0)
+#endif
+
static void
-delete_if_ordinary (name)
- const char *name;
+delete_if_ordinary (const char *name)
{
struct stat st;
#ifdef DEBUG
if (i == 'y' || i == 'Y')
#endif /* DEBUG */
- if (stat (name, &st) >= 0 && S_ISREG (st.st_mode))
- if (unlink (name) < 0)
- if (verbose_flag)
- perror_with_name (name);
+ DELETE_IF_ORDINARY (name, st, verbose_flag);
}
static void
-delete_temp_files ()
+delete_temp_files (void)
{
struct temp_file *temp;
/* Delete all the files to be deleted on error. */
static void
-delete_failure_queue ()
+delete_failure_queue (void)
{
struct temp_file *temp;
}
static void
-clear_failure_queue ()
+clear_failure_queue (void)
{
failure_delete_queue = 0;
}
It is also used by the --print-search-dirs flag. */
static char *
-build_search_list (paths, prefix, check_dir_p)
- struct path_prefix *paths;
- const char *prefix;
- int check_dir_p;
+build_search_list (struct path_prefix *paths, const char *prefix,
+ int check_dir_p)
{
int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
int just_suffix_len
for collect. */
static void
-putenv_from_prefixes (paths, env_var)
- struct path_prefix *paths;
- const char *env_var;
+putenv_from_prefixes (struct path_prefix *paths, const char *env_var)
{
putenv (build_search_list (paths, env_var, 1));
}
except that it never considers directories to be executable. */
static int
-access_check (name, mode)
- const char *name;
- int mode;
+access_check (const char *name, int mode)
{
if (mode == X_OK)
{
Return 0 if not found, otherwise return its name, allocated with malloc. */
static char *
-find_a_file (pprefix, name, mode, multilib)
- struct path_prefix *pprefix;
- const char *name;
- int mode, multilib;
+find_a_file (struct path_prefix *pprefix, const char *name, int mode,
+ int multilib)
{
char *temp;
const char *const file_suffix =
/* Determine the filename to execute (special case for absolute paths). */
- if (IS_ABSOLUTE_PATHNAME (name))
+ if (IS_ABSOLUTE_PATH (name))
{
if (access (name, mode) == 0)
{
strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
/* Now try just the multilib_name. */
strcat (temp, machine_suffix);
strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
/* Certain prefixes are tried with just the machine type,
strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
strcpy (temp, pl->prefix);
strcat (temp, just_machine_suffix);
strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
/* Certain prefixes can't be used without the machine suffix
strcat (temp, this_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
strcpy (temp, pl->prefix);
strcat (temp, this_name);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
}
2 means try both machine_suffix and just_machine_suffix. */
static void
-add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
- warn, os_multilib)
- struct path_prefix *pprefix;
- const char *prefix;
- const char *component;
- /* enum prefix_priority */ int priority;
- int require_machine_suffix;
- int *warn;
- int os_multilib;
+add_prefix (struct path_prefix *pprefix, const char *prefix,
+ const char *component, /* enum prefix_priority */ int priority,
+ int require_machine_suffix, int os_multilib)
{
struct prefix_list *pl, **prev;
int len;
prev = &(*prev)->next)
;
- /* Keep track of the longest prefix */
+ /* Keep track of the longest prefix. */
prefix = update_path (prefix, component);
len = strlen (prefix);
if (len > pprefix->max_len)
pprefix->max_len = len;
- pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
+ pl = xmalloc (sizeof (struct prefix_list));
pl->prefix = prefix;
pl->require_machine_suffix = require_machine_suffix;
- pl->used_flag_ptr = warn;
pl->priority = priority;
pl->os_multilib = os_multilib;
- if (warn)
- *warn = 0;
- /* Insert after PREV */
+ /* Insert after PREV. */
pl->next = (*prev);
(*prev) = pl;
}
/* Same as add_prefix, but prepending target_system_root to prefix. */
static void
-add_sysrooted_prefix (pprefix, prefix, component, priority,
- require_machine_suffix, warn, os_multilib)
- struct path_prefix *pprefix;
- const char *prefix;
- const char *component;
- /* enum prefix_priority */ int priority;
- int require_machine_suffix;
- int *warn;
- int os_multilib;
+add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
+ const char *component,
+ /* enum prefix_priority */ int priority,
+ int require_machine_suffix, int os_multilib)
{
- if (!IS_ABSOLUTE_PATHNAME (prefix))
- abort ();
+ if (!IS_ABSOLUTE_PATH (prefix))
+ fatal ("system path '%s' is not absolute", prefix);
if (target_system_root)
{
+ if (target_sysroot_suffix)
+ prefix = concat (target_sysroot_suffix, prefix, NULL);
prefix = concat (target_system_root, prefix, NULL);
+
/* We have to override this because GCC's notion of sysroot
moves along with GCC. */
component = "GCC";
}
add_prefix (pprefix, prefix, component, priority,
- require_machine_suffix, warn, os_multilib);
+ require_machine_suffix, os_multilib);
}
\f
/* Execute the command specified by the arguments on the current line of spec.
Return 0 if successful, -1 if failed. */
static int
-execute ()
+execute (void)
{
int i;
int n_commands; /* # of command. */
struct command *commands; /* each command buffer with above info. */
- if (processing_spec_function)
- abort ();
+ gcc_assert (!processing_spec_function);
/* Count # of piped commands. */
for (n_commands = 1, i = 0; i < argbuf_index; i++)
n_commands++;
/* Get storage for each command. */
- commands = (struct command *) alloca (n_commands * sizeof (struct command));
+ commands = alloca (n_commands * sizeof (struct command));
/* Split argbuf into its separate piped processes,
and record info about each one.
}
fflush (stderr);
if (verbose_only_flag != 0)
- return 0;
+ {
+ /* verbose_only_flag should act as if the spec was
+ executed, so increment execution_count before
+ returning. This prevents spurious warnings about
+ unused linker input files, etc. */
+ execution_count++;
+ return 0;
+ }
#ifdef DEBUG
notice ("\nGo ahead? (y or n) ");
fflush (stderr);
pfatal_pexecute (errmsg_fmt, errmsg_arg);
if (string != commands[i].prog)
- free ((PTR) string);
+ free ((void *) string);
}
execution_count++;
int pid;
pid = pwait (commands[i].pid, &status, 0);
- if (pid < 0)
- abort ();
+ gcc_assert (pid >= 0);
#ifdef HAVE_GETRUSAGE
if (report_times)
{
const char *name;
const char *language;
+ struct compiler *incompiler;
+ bool compiled;
+ bool preprocessed;
};
/* Also a vector of input files specified. */
int n_infiles;
+/* True if multiple input files are being compiled to a single
+ assembly file. */
+
+static bool combine_inputs;
+
/* This counts the number of libraries added by lang_specific_driver, so that
we can tell if there were any user supplied any files or libraries. */
/* And a vector of corresponding output files is made up later. */
const char **outfiles;
-
-/* Used to track if none of the -B paths are used. */
-static int warn_B;
-
-/* Gives value to pass as "warn" to add_prefix for standard prefixes. */
-static int *warn_std_ptr = 0;
\f
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
is true if we should look for an object suffix. */
static const char *
-convert_filename (name, do_exe, do_obj)
- const char *name;
- int do_exe ATTRIBUTE_UNUSED;
- int do_obj ATTRIBUTE_UNUSED;
+convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
+ int do_obj ATTRIBUTE_UNUSED)
{
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
int i;
\f
/* Display the command line switches accepted by gcc. */
static void
-display_help ()
+display_help (void)
{
printf (_("Usage: %s [options] file...\n"), programname);
fputs (_("Options:\n"), stdout);
fputs (_(" -Xassembler <arg> Pass <arg> on to the assembler\n"), stdout);
fputs (_(" -Xpreprocessor <arg> Pass <arg> on to the preprocessor\n"), stdout);
fputs (_(" -Xlinker <arg> Pass <arg> on to the linker\n"), stdout);
+ fputs (_(" -combine Pass multiple source files to compiler at once\n"), stdout);
fputs (_(" -save-temps Do not delete intermediate files\n"), stdout);
fputs (_(" -pipe Use pipes rather than intermediate files\n"), stdout);
fputs (_(" -time Time the execution of each subprocess\n"), stdout);
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);
}
static void
-add_preprocessor_option (option, len)
- const char *option;
- int len;
+add_preprocessor_option (const char *option, int len)
{
n_preprocessor_options++;
if (! preprocessor_options)
- preprocessor_options
- = (char **) xmalloc (n_preprocessor_options * sizeof (char *));
+ preprocessor_options = xmalloc (n_preprocessor_options * sizeof (char *));
else
- preprocessor_options
- = (char **) xrealloc (preprocessor_options,
- n_preprocessor_options * sizeof (char *));
+ preprocessor_options = xrealloc (preprocessor_options,
+ n_preprocessor_options * sizeof (char *));
preprocessor_options [n_preprocessor_options - 1] =
save_string (option, len);
}
static void
-add_assembler_option (option, len)
- const char *option;
- int len;
+add_assembler_option (const char *option, int len)
{
n_assembler_options++;
if (! assembler_options)
- assembler_options
- = (char **) xmalloc (n_assembler_options * sizeof (char *));
+ assembler_options = xmalloc (n_assembler_options * sizeof (char *));
else
- assembler_options
- = (char **) xrealloc (assembler_options,
- n_assembler_options * sizeof (char *));
+ assembler_options = xrealloc (assembler_options,
+ n_assembler_options * sizeof (char *));
assembler_options [n_assembler_options - 1] = save_string (option, len);
}
static void
-add_linker_option (option, len)
- const char *option;
- int len;
+add_linker_option (const char *option, int len)
{
n_linker_options++;
if (! linker_options)
- linker_options
- = (char **) xmalloc (n_linker_options * sizeof (char *));
+ linker_options = xmalloc (n_linker_options * sizeof (char *));
else
- linker_options
- = (char **) xrealloc (linker_options,
- n_linker_options * sizeof (char *));
+ linker_options = xrealloc (linker_options,
+ n_linker_options * sizeof (char *));
linker_options [n_linker_options - 1] = save_string (option, len);
}
Store its length in `n_switches'. */
static void
-process_command (argc, argv)
- int argc;
- const char *const *argv;
+process_command (int argc, const char **argv)
{
int i;
const char *temp;
const char *spec_lang = 0;
int last_language_n_infiles;
int have_c = 0;
- int have_o = 0;
int lang_n_infiles = 0;
#ifdef MODIFY_TARGET_NAME
int is_modify_target_name;
char **new_argv;
char *new_argv0;
int baselen;
-
+
while (argc > 1 && argv[1][0] == '-'
&& (argv[1][1] == 'V' || argv[1][1] == 'b'))
{
argv += 2;
}
else
- fatal ("`-%c' option must have argument", opt);
+ fatal ("'-%c' option must have argument", opt);
if (opt == 'V')
new_version = arg;
else
for (baselen = strlen (progname); baselen > 0; baselen--)
if (IS_DIR_SEPARATOR (progname[baselen-1]))
break;
- new_argv0 = xmemdup (progname, baselen,
+ new_argv0 = xmemdup (progname, baselen,
baselen + concat_length (new_version, new_machine,
"-gcc-", NULL) + 1);
strcpy (new_argv0 + baselen, new_machine);
new_argv[0] = new_argv0;
execvp (new_argv0, new_argv);
- fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
+ fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno));
}
/* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
see if we can create it from the pathname specified in argv[0]. */
+ gcc_libexec_prefix = standard_libexec_prefix;
#ifndef VMS
/* FIXME: make_relative_prefix doesn't yet work for VMS. */
if (!gcc_exec_prefix)
{
gcc_exec_prefix = make_relative_prefix (argv[0], standard_bindir_prefix,
standard_exec_prefix);
+ gcc_libexec_prefix = make_relative_prefix (argv[0],
+ standard_bindir_prefix,
+ standard_libexec_prefix);
if (gcc_exec_prefix)
putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
}
+ else
+ gcc_libexec_prefix = make_relative_prefix (gcc_exec_prefix,
+ standard_exec_prefix,
+ standard_libexec_prefix);
+#else
#endif
if (gcc_exec_prefix)
{
int len = strlen (gcc_exec_prefix);
- if (len > (int) sizeof ("/lib/gcc-lib/") - 1
+ if (len > (int) sizeof ("/lib/gcc/") - 1
&& (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
{
- temp = gcc_exec_prefix + len - sizeof ("/lib/gcc-lib/") + 1;
+ temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
if (IS_DIR_SEPARATOR (*temp)
&& strncmp (temp + 1, "lib", 3) == 0
&& IS_DIR_SEPARATOR (temp[4])
- && strncmp (temp + 5, "gcc-lib", 7) == 0)
- len -= sizeof ("/lib/gcc-lib/") - 1;
+ && strncmp (temp + 5, "gcc", 3) == 0)
+ len -= sizeof ("/lib/gcc/") - 1;
}
set_std_prefix (gcc_exec_prefix, len);
- add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
+ PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
}
/* COMPILER_PATH and LIBRARY_PATH have values
if (temp)
{
const char *startp, *endp;
- char *nstore = (char *) alloca (strlen (temp) + 3);
+ char *nstore = alloca (strlen (temp) + 3);
startp = endp = temp;
while (1)
else
nstore[endp - startp] = 0;
add_prefix (&exec_prefixes, nstore, 0,
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
- add_prefix (&include_prefixes,
- concat (nstore, "include", NULL),
- 0, PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
+ add_prefix (&include_prefixes, nstore, 0,
+ PREFIX_PRIORITY_LAST, 0, 0);
if (*endp == 0)
break;
endp = startp = endp + 1;
if (temp && *cross_compile == '0')
{
const char *startp, *endp;
- char *nstore = (char *) alloca (strlen (temp) + 3);
+ char *nstore = alloca (strlen (temp) + 3);
startp = endp = temp;
while (1)
else
nstore[endp - startp] = 0;
add_prefix (&startfile_prefixes, nstore, NULL,
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
if (*endp == 0)
break;
endp = startp = endp + 1;
if (temp && *cross_compile == '0')
{
const char *startp, *endp;
- char *nstore = (char *) alloca (strlen (temp) + 3);
+ char *nstore = alloca (strlen (temp) + 3);
startp = endp = temp;
while (1)
else
nstore[endp - startp] = 0;
add_prefix (&startfile_prefixes, nstore, NULL,
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
if (*endp == 0)
break;
endp = startp = endp + 1;
}
/* Convert new-style -- options to old-style. */
- translate_options (&argc, &argv);
+ translate_options (&argc, (const char *const **) &argv);
/* Do language-specific adjustment/addition of flags. */
- lang_specific_driver (&argc, &argv, &added_libraries);
+ lang_specific_driver (&argc, (const char *const **) &argv, &added_libraries);
/* Scan argv twice. Here, the first time, just count how many switches
there will be in their vector, and how many input files in theirs.
{
/* translate_options () has turned --version into -fversion. */
printf (_("%s (GCC) %s\n"), programname, version_string);
- fputs (_("Copyright (C) 2002 Free Software Foundation, Inc.\n"),
- stdout);
+ printf ("Copyright %s 2004 Free Software Foundation, Inc.\n",
+ _("(C)"));
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"),
stdout);
else if (strcmp (argv[i], "-Xlinker") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xlinker' is missing");
+ fatal ("argument to '-Xlinker' is missing");
n_infiles++;
i++;
else if (strcmp (argv[i], "-Xpreprocessor") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xpreprocessor' is missing");
+ fatal ("argument to '-Xpreprocessor' is missing");
add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
}
else if (strcmp (argv[i], "-Xassembler") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xassembler' is missing");
+ fatal ("argument to '-Xassembler' is missing");
add_assembler_option (argv[i+1], strlen (argv[i+1]));
}
else if (strcmp (argv[i], "-l") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-l' is missing");
+ fatal ("argument to '-l' is missing");
n_infiles++;
i++;
save_temps_flag = 1;
n_switches++;
}
+ else if (strcmp (argv[i], "-combine") == 0)
+ {
+ combine_flag = 1;
+ n_switches++;
+ }
else if (strcmp (argv[i], "-specs") == 0)
{
- struct user_specs *user = (struct user_specs *)
- xmalloc (sizeof (struct user_specs));
+ struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (++i >= argc)
- fatal ("argument to `-specs' is missing");
+ fatal ("argument to '-specs' is missing");
user->next = (struct user_specs *) 0;
user->filename = argv[i];
}
else if (strncmp (argv[i], "-specs=", 7) == 0)
{
- struct user_specs *user = (struct user_specs *)
- xmalloc (sizeof (struct user_specs));
+ struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (strlen (argv[i]) == 7)
- fatal ("argument to `-specs=' is missing");
+ fatal ("argument to '-specs=' is missing");
user->next = (struct user_specs *) 0;
user->filename = argv[i] + 7;
{
case 'b':
case 'V':
- fatal ("`-%c' must come at the start of the command line", c);
+ fatal ("'-%c' must come at the start of the command line", c);
break;
case 'B':
int len;
if (p[1] == 0 && i + 1 == argc)
- fatal ("argument to `-B' is missing");
+ fatal ("argument to '-B' is missing");
if (p[1] == 0)
value = argv[++i];
else
&& (IS_DIR_SEPARATOR (value[len - 1])))
{
if (len == 7)
- add_prefix (&include_prefixes, "include", NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ add_prefix (&include_prefixes, "./", NULL,
+ PREFIX_PRIORITY_B_OPT, 0, 0);
else
{
- char * string = xmalloc (len + 1);
-
- strncpy (string, value, len - 7);
- strcpy (string + len - 7, "include");
- add_prefix (&include_prefixes, string, NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ char *string = xmalloc (len - 6);
+ memcpy (string, value, len - 7);
+ string[len - 7] = 0;
+ add_prefix (&include_prefixes, string, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, 0);
}
}
add_prefix (&exec_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
add_prefix (&startfile_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
- add_prefix (&include_prefixes, concat (value, "include", NULL),
- NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
+ add_prefix (&include_prefixes, value, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, 0);
n_switches++;
}
break;
goto normal_switch;
case 'o':
- have_o = 1;
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
if (! have_c)
{
for (j = 0; j < ARRAY_SIZE (modify_target); j++)
if (! strcmp (argv[i], modify_target[j].sw))
{
- char *new_name
- = (char *) xmalloc (strlen (modify_target[j].str)
- + strlen (spec_machine));
+ char *new_name = xmalloc (strlen (modify_target[j].str)
+ + strlen (spec_machine));
const char *p, *r;
char *q;
int made_addition = 0;
}
}
- if (have_c && have_o && lang_n_infiles > 1)
- fatal ("cannot specify -o with -c or -S and multiple compilations");
-
if ((save_temps_flag || report_times) && use_pipes)
{
/* -save-temps overrides -pipe, so that temp files are produced */
use_pipes = 0;
}
-
+
/* Set up the search paths before we go looking for config files. */
/* These come before the md prefixes so that we will find gcc's subcommands
/* Use 2 as fourth arg meaning try just the machine as a suffix,
as well as trying the machine and the version. */
#ifndef OS2
- add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+ add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
+ PREFIX_PRIORITY_LAST, 1, 0);
+ add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, 0);
add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 2, 0);
add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 2, 0);
+ add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, 0);
#endif
add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
- add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 1, 0);
+ add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 1, 0);
tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
dir_separator_str, NULL);
directories, so that we can search both the user specified directory
and the standard place. */
- if (!IS_ABSOLUTE_PATHNAME (tooldir_prefix))
+ if (!IS_ABSOLUTE_PATH (tooldir_prefix))
{
if (gcc_exec_prefix)
{
add_prefix (&exec_prefixes,
concat (gcc_exec_tooldir_prefix, "bin",
dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ NULL, PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&startfile_prefixes,
concat (gcc_exec_tooldir_prefix, "lib",
dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
}
tooldir_prefix = concat (standard_exec_prefix, spec_machine,
add_prefix (&exec_prefixes,
concat (tooldir_prefix, "bin", dir_separator_str, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&startfile_prefixes,
concat (tooldir_prefix, "lib", dir_separator_str, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
/* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
/* Then create the space for the vectors and scan again. */
- switches = ((struct switchstr *)
- xmalloc ((n_switches + 1) * sizeof (struct switchstr)));
- infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile));
+ switches = xmalloc ((n_switches + 1) * sizeof (struct switchstr));
+ infiles = xmalloc ((n_infiles + 1) * sizeof (struct infile));
n_switches = 0;
n_infiles = 0;
last_language_n_infiles = -1;
if (c == 'x')
{
if (p[1] == 0 && i + 1 == argc)
- fatal ("argument to `-x' is missing");
+ fatal ("argument to '-x' is missing");
if (p[1] == 0)
spec_lang = argv[++i];
else
n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
}
if (i + n_args >= argc)
- fatal ("argument to `-%s' is missing", p);
+ fatal ("argument to '-%s' is missing", p);
switches[n_switches].args
- = (const char **) xmalloc ((n_args + 1) * sizeof(const char *));
+ = xmalloc ((n_args + 1) * sizeof(const char *));
while (j < n_args)
switches[n_switches].args[j++] = argv[++i];
/* Null-terminate the vector. */
{
/* On some systems, ld cannot handle some options without
a space. So split the option from its argument. */
- char *part1 = (char *) xmalloc (2);
+ char *part1 = xmalloc (2);
part1[0] = c;
part1[1] = '\0';
switches[n_switches].part1 = part1;
- switches[n_switches].args
- = (const char **) xmalloc (2 * sizeof (const char *));
+ switches[n_switches].args = xmalloc (2 * sizeof (const char *));
switches[n_switches].args[0] = xstrdup (p+1);
switches[n_switches].args[1] = 0;
}
}
if (n_infiles == last_language_n_infiles && spec_lang != 0)
- error ("warning: `-x %s' after last input file has no effect", spec_lang);
+ error ("warning: '-x %s' after last input file has no effect", spec_lang);
/* Ensure we only invoke each subprocess once. */
if (target_help_flag || print_help_list)
and place that in the environment. */
static void
-set_collect_gcc_options ()
+set_collect_gcc_options (void)
{
int i;
int first_time;
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;
static int suffixed_basename_length;
static const char *input_basename;
static const char *input_suffix;
+#ifndef HOST_LACKS_INODE_NUMBERS
static struct stat input_stat;
+#endif
static int input_stat_set;
/* The compiler used to process the current input file. */
Returns 0 if the spec is successfully processed; -1 if failed. */
int
-do_spec (spec)
- const char *spec;
+do_spec (const char *spec)
{
int value;
}
static int
-do_spec_2 (spec)
- const char *spec;
+do_spec_2 (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_self_spec (spec)
- const char *spec;
+do_option_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 (const char *spec)
{
do_spec_2 (spec);
do_spec_1 (" ", 0, NULL);
/* Each switch should start with '-'. */
if (argbuf[i][0] != '-')
- abort ();
+ fatal ("switch '%s' does not start with '-'", argbuf[i]);
sw = &switches[i + first];
sw->part1 = &argbuf[i][1];
}
}
+void
+do_spec_path (struct prefix_list *pl, const char *option,
+ int omit_if_relative, int separate_options,
+ int only_subdir,
+ const char *dir_for_machine_suffix,
+ const char *dir_for_no_suffix)
+{
+ static size_t bufsize = 0;
+ static char *buffer;
+ int idx;
+
+ /* Used on systems which record the specified -L dirs
+ and use them to search for dynamic linking. */
+ /* Relative directories always come from -B,
+ and it is better not to use them for searching
+ at run time. In particular, stage1 loses. */
+ if (omit_if_relative
+ && !IS_ABSOLUTE_PATH (pl->prefix))
+ return;
+
+ /* Try subdirectory if there is one. */
+ if (machine_suffix && dir_for_machine_suffix)
+ {
+ if (strlen (pl->prefix) + strlen (machine_suffix)
+ >= bufsize)
+ bufsize = (strlen (pl->prefix)
+ + strlen (machine_suffix)) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, pl->prefix);
+ strcat (buffer, machine_suffix);
+ if (is_directory (buffer, dir_for_machine_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (buffer, 1, NULL);
+ do_spec_1 (dir_for_machine_suffix, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+ if (!pl->require_machine_suffix && dir_for_no_suffix)
+ {
+ if (is_directory (pl->prefix, dir_for_no_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (pl->prefix, 1, NULL);
+ do_spec_1 (dir_for_no_suffix, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+
+ if (only_subdir)
+ return;
+
+ if (machine_suffix)
+ {
+ if (is_directory (pl->prefix, machine_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (pl->prefix, 1, NULL);
+ /* Remove slash from machine_suffix. */
+ if (strlen (machine_suffix) >= bufsize)
+ bufsize = strlen (machine_suffix) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, machine_suffix);
+ idx = strlen (buffer);
+ if (IS_DIR_SEPARATOR (buffer[idx - 1]))
+ buffer[idx - 1] = 0;
+ do_spec_1 (buffer, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+ if (!pl->require_machine_suffix)
+ {
+ if (is_directory (pl->prefix, "", 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ /* Remove slash from pl->prefix. */
+ if (strlen (pl->prefix) >= bufsize)
+ bufsize = strlen (pl->prefix) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, pl->prefix);
+ idx = strlen (buffer);
+ if (IS_DIR_SEPARATOR (buffer[idx - 1]))
+ buffer[idx - 1] = 0;
+ do_spec_1 (buffer, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+}
+
/* Process the sub-spec SPEC as a portion of a larger spec.
This is like processing a whole spec except that we do
not initialize at the beginning and we do not supply a
and the command on that line reported an error. */
static int
-do_spec_1 (spec, inswitch, soft_matched_part)
- const char *spec;
- int inswitch;
- const char *soft_matched_part;
+do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
{
const char *p = spec;
int c;
switch (c = *p++)
{
case 0:
- fatal ("invalid specification! Bug in cc");
+ fatal ("spec '%s' invalid", spec);
case 'b':
obstack_grow (&obstack, input_basename, basename_length);
case 'D':
{
struct prefix_list *pl = startfile_prefixes.plist;
- size_t bufsize = 100;
- char *buffer = (char *) xmalloc (bufsize);
- int idx;
for (; pl; pl = pl->next)
{
-#ifdef RELATIVE_PREFIX_NOT_LINKDIR
- /* Used on systems which record the specified -L dirs
- and use them to search for dynamic linking. */
- /* Relative directories always come from -B,
- and it is better not to use them for searching
- at run time. In particular, stage1 loses. */
- if (!IS_ABSOLUTE_PATHNAME (pl->prefix))
- continue;
-#endif
- /* Try subdirectory if there is one. */
- if (multilib_dir != NULL
- || (pl->os_multilib && multilib_os_dir != NULL))
- {
- const char *multi_dir;
+ const char *no_suffix_multilib_dir;
- multi_dir = pl->os_multilib ? multilib_os_dir
- : multilib_dir;
- if (machine_suffix && multilib_dir)
- {
- if (strlen (pl->prefix) + strlen (machine_suffix)
- >= bufsize)
- bufsize = (strlen (pl->prefix)
- + strlen (machine_suffix)) * 2 + 1;
- buffer = (char *) xrealloc (buffer, bufsize);
- strcpy (buffer, pl->prefix);
- strcat (buffer, machine_suffix);
- if (is_directory (buffer, multilib_dir, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (buffer, 1, NULL);
- do_spec_1 (multilib_dir, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- if (!pl->require_machine_suffix)
- {
- if (is_directory (pl->prefix, multi_dir, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (multi_dir, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- }
- if (machine_suffix)
- {
- if (is_directory (pl->prefix, machine_suffix, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (pl->prefix, 1, NULL);
- /* Remove slash from machine_suffix. */
- if (strlen (machine_suffix) >= bufsize)
- bufsize = strlen (machine_suffix) * 2 + 1;
- buffer = (char *) xrealloc (buffer, bufsize);
- strcpy (buffer, machine_suffix);
- idx = strlen (buffer);
- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
- buffer[idx - 1] = 0;
- do_spec_1 (buffer, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- if (!pl->require_machine_suffix)
- {
- if (is_directory (pl->prefix, "", 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
+ no_suffix_multilib_dir = pl->os_multilib ? multilib_os_dir
+ : multilib_dir;
+ /* Do not separate options, include non-multilibbed variant. */
+ do_spec_path (pl, "-L",
+#ifdef RELATIVE_PREFIX_NOT_LINKDIR
+ 1,
+#else
+ 0,
#endif
- /* Remove slash from pl->prefix. */
- if (strlen (pl->prefix) >= bufsize)
- bufsize = strlen (pl->prefix) * 2 + 1;
- buffer = (char *) xrealloc (buffer, bufsize);
- strcpy (buffer, pl->prefix);
- idx = strlen (buffer);
- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
- buffer[idx - 1] = 0;
- do_spec_1 (buffer, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
+ 0, 0, multilib_dir, no_suffix_multilib_dir);
}
- free (buffer);
}
break;
char *buf;
while (*p != 0 && *p != '\n')
p++;
- buf = (char *) alloca (p - q + 1);
+ buf = alloca (p - q + 1);
strncpy (buf, q, p - q);
buf[p - q] = 0;
error ("%s", buf);
char *buf;
while (*p != 0 && *p != '\n')
p++;
- buf = (char *) alloca (p - q + 1);
+ buf = alloca (p - q + 1);
strncpy (buf, q, p - q);
buf[p - q] = 0;
notice ("%s\n", buf);
p++;
if (p[0] == '%' && p[1] == 'O')
p += 2;
-
+
break;
}
goto create_temp_file;
p++;
if (p[0] == '%' && p[1] == 'O')
p += 2;
-
+
break;
}
goto create_temp_file;
p += 2;
/* We don't support extra suffix characters after %O. */
if (*p == '.' || ISALPHA ((unsigned char) *p))
- abort ();
+ fatal ("spec '%s' has invalid '%%0%c'", spec, *p);
if (suffix_length == 0)
suffix = TARGET_OBJECT_SUFFIX;
else
{
saved_suffix
- = (char *) xmalloc (suffix_length
- + strlen (TARGET_OBJECT_SUFFIX));
+ = xmalloc (suffix_length
+ + strlen (TARGET_OBJECT_SUFFIX));
strncpy (saved_suffix, suffix, suffix_length);
strcpy (saved_suffix + suffix_length,
TARGET_OBJECT_SUFFIX);
temp_filename = alloca (temp_filename_length + 1);
strncpy ((char *) temp_filename, input_basename, basename_length);
strncpy ((char *) temp_filename + basename_length, suffix,
- suffix_length);
+ suffix_length);
*((char *) temp_filename + temp_filename_length) = '\0';
if (strcmp (temp_filename, input_filename) != 0)
{
- struct stat st_temp;
-
- /* Note, set_input() resets input_stat_set to 0. */
- if (input_stat_set == 0)
- {
- input_stat_set = stat (input_filename, &input_stat);
- if (input_stat_set >= 0)
- input_stat_set = 1;
- }
+#ifndef HOST_LACKS_INODE_NUMBERS
+ struct stat st_temp;
- /* If we have the stat for the input_filename
- and we can do the stat for the temp_filename
- then the they could still refer to the same
- file if st_dev/st_ino's are the same. */
+ /* Note, set_input() resets input_stat_set to 0. */
+ if (input_stat_set == 0)
+ {
+ input_stat_set = stat (input_filename, &input_stat);
+ if (input_stat_set >= 0)
+ input_stat_set = 1;
+ }
+ /* If we have the stat for the input_filename
+ and we can do the stat for the temp_filename
+ then the they could still refer to the same
+ file if st_dev/st_ino's are the same. */
if (input_stat_set != 1
|| stat (temp_filename, &st_temp) < 0
|| input_stat.st_dev != st_temp.st_dev
|| input_stat.st_ino != st_temp.st_ino)
+#else
+ /* Just compare canonical pathnames. */
+ char* input_realname = lrealpath (input_filename);
+ char* temp_realname = lrealpath (temp_filename);
+ bool files_differ = strcmp (input_realname, temp_realname);
+ free (input_realname);
+ free (temp_realname);
+ if (files_differ)
+#endif
{
temp_filename = save_string (temp_filename,
temp_filename_length + 1);
obstack_grow (&obstack, temp_filename,
- temp_filename_length);
+ temp_filename_length);
arg_going = 1;
delete_this_arg = 0;
break;
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
{
if (t == 0)
{
- t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
+ t = xmalloc (sizeof (struct temp_name));
t->next = temp_names;
temp_names = t;
}
}
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;
break;
case 'i':
- obstack_grow (&obstack, input_filename, input_filename_length);
- arg_going = 1;
+ if (combine_inputs)
+ {
+ for (i = 0; (int) i < n_infiles; i++)
+ if ((!infiles[i].language) || (infiles[i].language[0] != '*'))
+ if (infiles[i].incompiler == input_file_compiler)
+ {
+ store_arg (infiles[i].name, 0, 0);
+ infiles[i].compiled = true;
+ }
+ }
+ else
+ {
+ obstack_grow (&obstack, input_filename, input_filename_length);
+ arg_going = 1;
+ }
break;
case 'I':
do_spec_1 (" ", 0, NULL);
}
- if (target_system_root_changed)
+ if (target_system_root_changed ||
+ (target_system_root && target_sysroot_hdrs_suffix))
{
do_spec_1 ("-isysroot", 1, NULL);
/* Make this a separate argument. */
do_spec_1 (" ", 0, NULL);
do_spec_1 (target_system_root, 1, NULL);
+ if (target_sysroot_hdrs_suffix)
+ do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
do_spec_1 (" ", 0, NULL);
}
for (; pl; pl = pl->next)
- {
- do_spec_1 ("-isystem", 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (" ", 0, NULL);
- }
+ /* Separate options, don't include non-suffixed variant. */
+ do_spec_path (pl, "-isystem", 0, 1, 1, "include", "include");
}
break;
int cur_index = argbuf_index;
/* Handle the {...} following the %W. */
if (*p != '{')
- abort ();
+ fatal ("spec '%s' has invalid '%%W%c", spec, *p);
p = handle_braces (p + 1);
if (p == 0)
return -1;
/* Skip past the option value and make a copy. */
if (*p != '{')
- abort ();
+ fatal ("spec '%s' has invalid '%%x%c'", spec, *p);
while (*p++ != '}')
;
string = save_string (p1 + 1, p - p1 - 2);
}
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. */
if (target_system_root)
- obstack_grow (&obstack, target_system_root,
- strlen (target_system_root));
+ {
+ obstack_grow (&obstack, target_system_root,
+ strlen (target_system_root));
+ if (target_sysroot_suffix)
+ obstack_grow (&obstack, target_sysroot_suffix,
+ strlen (target_sysroot_suffix));
+ }
break;
case 'S':
p = handle_braces (p);
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;
- }
break;
case ':':
}
else
/* Catch the case where a spec string contains something like
- '%{foo:%*}'. ie there is no * in the pattern on the left
+ '%{foo:%*}'. i.e. there is no * in the pattern on the left
hand side of the :. */
error ("spec failure: '%%*' has not been initialized by pattern match");
break;
}
else
{
- char *x = (char *) alloca (strlen (name) * 2 + 1);
+ char *x = alloca (strlen (name) * 2 + 1);
char *buf = x;
const char *y = name;
int flag = 0;
}
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;
/* Backslash: treat next character as ordinary. */
c = *p++;
- /* fall through */
+ /* Fall through. */
default:
/* Ordinary character: put it into the current argument. */
obstack_1grow (&obstack, c);
/* Look up a spec function. */
static const struct spec_function *
-lookup_spec_function (name)
- const char *name;
+lookup_spec_function (const char *name)
{
static const struct spec_function * const spec_function_tables[] =
{
/* Evaluate a spec function. */
static const char *
-eval_spec_function (func, args)
- const char *func, *args;
+eval_spec_function (const char *func, const char *args)
{
const struct spec_function *sf;
const char *funcval;
sf = lookup_spec_function (func);
if (sf == NULL)
- fatal ("unknown spec function `%s'", func);
+ fatal ("unknown spec function '%s'", func);
/* Push the spec processing context. */
save_argbuf_index = argbuf_index;
alloc_args ();
if (do_spec_2 (args) < 0)
- fatal ("error in args to spec function `%s'", func);
+ fatal ("error in args to spec function '%s'", func);
/* argbuf_index is an index for the next argument to be inserted, and
so contains the count of the args already inserted. */
NULL if no processing is required. */
static const char *
-handle_spec_function (p)
- const char *p;
+handle_spec_function (const char *p)
{
char *func, *args;
const char *endp, *funcval;
/* Inline subroutine of handle_braces. Returns true if the current
input suffix matches the atom bracketed by ATOM and END_ATOM. */
static inline bool
-input_suffix_matches (atom, end_atom)
- const char *atom;
- const char *end_atom;
+input_suffix_matches (const char *atom, const char *end_atom)
{
return (input_suffix
&& !strncmp (input_suffix, atom, end_atom - atom)
matching the atom bracketed by ATOM and END_ATOM appeared on the
command line. */
static inline bool
-switch_matches (atom, end_atom, starred)
- const char *atom;
- const char *end_atom;
- int starred;
+switch_matches (const char *atom, const char *end_atom, int starred)
{
int i;
int len = end_atom - atom;
match ATOM (extends to END_ATOM; STARRED indicates whether there
was a star after the atom) for later processing. */
static inline void
-mark_matching_switches (atom, end_atom, starred)
- const char *atom;
- const char *end_atom;
- int starred;
+mark_matching_switches (const char *atom, const char *end_atom, int starred)
{
int i;
int len = end_atom - atom;
/* Inline subroutine of handle_braces. Process all the currently
marked switches through give_switch, and clear the marks. */
static inline void
-process_marked_switches ()
+process_marked_switches (void)
{
int i;
if we call do_spec_1 and that returns -1. */
static const char *
-handle_braces (p)
- const char *p;
+handle_braces (const char *p)
{
const char *atom, *end_atom;
const char *d_atom = NULL, *d_end_atom = NULL;
+ const char *orig = p;
bool a_is_suffix;
bool a_is_starred;
do
{
if (a_must_be_last)
- abort ();
+ goto invalid;
/* Scan one "atom" (S in the description above of %{}, possibly
with !, ., or * modifiers). */
p++, a_is_starred = 1;
SKIP_WHITE();
- if (*p == '&' || *p == '}')
+ switch (*p)
{
+ case '&': case '}':
/* Substitute the switch(es) indicated by the current atom. */
ordered_set = true;
if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
|| atom == end_atom)
- abort ();
+ goto invalid;
mark_matching_switches (atom, end_atom, a_is_starred);
if (*p == '}')
process_marked_switches ();
- }
- else if (*p == '|' || *p == ':')
- {
+ break;
+
+ case '|': case ':':
/* Substitute some text if the current atom appears as a switch
or suffix. */
disjunct_set = true;
if (ordered_set)
- abort ();
+ goto invalid;
if (atom == end_atom)
{
if (!n_way_choice || disj_matched || *p == '|'
|| a_is_negated || a_is_suffix || a_is_starred)
- abort ();
+ goto invalid;
/* An empty term may appear as the last choice of an
N-way choice set; it means "otherwise". */
else
{
if (a_is_suffix && a_is_starred)
- abort ();
+ goto invalid;
if (!a_is_starred)
disj_starred = false;
d_atom = d_end_atom = NULL;
}
}
+ break;
+
+ default:
+ goto invalid;
}
- else
- abort ();
}
while (*p++ != '}');
return p;
-
+
+ invalid:
+ fatal ("braced spec '%s' is invalid at '%c'", orig, *p);
+
#undef SKIP_WHITE
}
returns -1. */
static const char *
-process_brace_body (p, atom, end_atom, starred, matched)
- const char *p;
- const char *atom;
- const char *end_atom;
- int starred;
- int matched;
+process_brace_body (const char *p, const char *atom, const char *end_atom,
+ int starred, int matched)
{
const char *body, *end_body;
unsigned int nesting_level;
else if (*p == '%' && p[1] == '*' && nesting_level == 1)
have_subst = true;
else if (*p == '\0')
- abort ();
+ goto invalid;
p++;
}
-
+
end_body = p;
while (end_body[-1] == ' ' || end_body[-1] == '\t')
end_body--;
if (have_subst && !starred)
- abort ();
+ goto invalid;
if (matched)
{
}
return p;
+
+ invalid:
+ fatal ("braced spec body '%s' is invalid", body);
}
\f
/* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
with the "no-", similarly for a switch with the "no-" prefix. */
static int
-check_live_switch (switchnum, prefix_length)
- int switchnum;
- int prefix_length;
+check_live_switch (int switchnum, int prefix_length)
{
const char *name = switches[switchnum].part1;
int i;
If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */
static void
-give_switch (switchnum, omit_first_word)
- int switchnum;
- int omit_first_word;
+give_switch (int switchnum, int omit_first_word)
{
if (switches[switchnum].live_cond == SWITCH_IGNORE)
return;
Return the absolute file name found. If nothing is found, return NAME. */
static const char *
-find_file (name)
- const char *name;
+find_file (const char *name)
{
char *newname;
limit. */
static int
-is_directory (path1, path2, linker)
- const char *path1;
- const char *path2;
- int linker;
+is_directory (const char *path1, const char *path2, int linker)
{
int len1 = strlen (path1);
int len2 = strlen (path2);
- char *path = (char *) alloca (3 + len1 + len2);
+ char *path = alloca (3 + len1 + len2);
char *cp;
struct stat st;
the input file named FILENAME. */
void
-set_input (filename)
- const char *filename;
+set_input (const char *filename)
{
const char *p;
/* On fatal signals, delete all the temporary files. */
static void
-fatal_error (signum)
- int signum;
+fatal_error (int signum)
{
signal (signum, SIG_DFL);
delete_failure_queue ();
kill (getpid (), signum);
}
-extern int main PARAMS ((int, const char *const *));
+extern int main (int, const char **);
int
-main (argc, argv)
- int argc;
- const char *const *argv;
+main (int argc, const char **argv)
{
size_t i;
int value;
int linker_was_run = 0;
+ int lang_n_infiles = 0;
int num_linker_inputs = 0;
char *explicit_link_files;
char *specs_file;
/* Initialize the vector of specs to just the default.
This means one element containing 0s, as a terminator. */
- compilers = (struct compiler *) xmalloc (sizeof default_compilers);
- memcpy ((char *) compilers, (char *) default_compilers,
- sizeof default_compilers);
+ compilers = xmalloc (sizeof default_compilers);
+ memcpy (compilers, default_compilers, sizeof default_compilers);
n_compilers = n_default_compilers;
/* Read specs from a file if there is one. */
/* We need to check standard_exec_prefix/just_machine_suffix/specs
for any override of as, ld and libraries. */
- specs_file = (char *) alloca (strlen (standard_exec_prefix)
- + strlen (just_machine_suffix)
- + sizeof ("specs"));
+ specs_file = alloca (strlen (standard_exec_prefix)
+ + strlen (just_machine_suffix) + sizeof ("specs"));
strcpy (specs_file, standard_exec_prefix);
strcat (specs_file, just_machine_suffix);
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. */
if (*md_exec_prefix)
{
add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
}
}
+ /* Process sysroot_suffix_spec. */
+ if (*sysroot_suffix_spec != 0
+ && do_spec_2 (sysroot_suffix_spec) == 0)
+ {
+ if (argbuf_index > 1)
+ error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC.");
+ else if (argbuf_index == 1)
+ target_sysroot_suffix = xstrdup (argbuf[argbuf_index -1]);
+ }
+
+ /* Process sysroot_hdrs_suffix_spec. */
+ if (*sysroot_hdrs_suffix_spec != 0
+ && do_spec_2 (sysroot_hdrs_suffix_spec) == 0)
+ {
+ if (argbuf_index > 1)
+ error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC.");
+ else if (argbuf_index == 1)
+ target_sysroot_hdrs_suffix = xstrdup (argbuf[argbuf_index -1]);
+ }
+
/* Look for startfiles in the standard places. */
if (*startfile_prefix_spec != 0
&& do_spec_2 (startfile_prefix_spec) == 0
int ndx;
for (ndx = 0; ndx < argbuf_index; ndx++)
add_sysrooted_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
}
/* We should eventually get rid of all these and stick to
startfile_prefix_spec exclusively. */
{
if (*md_exec_prefix)
add_sysrooted_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
if (*md_startfile_prefix)
add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
- "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ "GCC", PREFIX_PRIORITY_LAST, 0, 1);
if (*md_startfile_prefix_1)
add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
- "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ "GCC", PREFIX_PRIORITY_LAST, 0, 1);
/* If standard_startfile_prefix is relative, base it on
standard_exec_prefix. This lets us move the installed tree
as a unit. If GCC_EXEC_PREFIX is defined, base
- standard_startfile_prefix on that as well. */
- if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix))
+ standard_startfile_prefix on that as well.
+
+ If the prefix is relative, only search it for native compilers;
+ otherwise we will search a directory containing host libraries. */
+ if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
add_sysrooted_prefix (&startfile_prefixes,
standard_startfile_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
- else
+ PREFIX_PRIORITY_LAST, 0, 1);
+ else if (*cross_compile == '0')
{
if (gcc_exec_prefix)
add_prefix (&startfile_prefixes,
concat (gcc_exec_prefix, machine_suffix,
standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
add_prefix (&startfile_prefixes,
concat (standard_exec_prefix,
machine_suffix,
standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
}
- add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_1,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
- add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_2,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
-#if 0 /* Can cause surprises, and one can use -B./ instead. */
- add_prefix (&startfile_prefixes, "./", NULL,
- PREFIX_PRIORITY_LAST, 1, NULL, 0);
-#endif
+ if (*standard_startfile_prefix_1)
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix_1, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, 1);
+ if (*standard_startfile_prefix_2)
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, 1);
}
/* Process any user specified specs in the order given on the command
for (i = 0; (int) i < n_switches; i++)
if (! switches[i].validated)
- error ("unrecognized option `-%s'", switches[i].part1);
+ error ("unrecognized option '-%s'", switches[i].part1);
/* Obey some of the options. */
i = n_infiles;
i += lang_specific_extra_outfiles;
- outfiles = (const char **) xcalloc (i, sizeof (char *));
+ outfiles = xcalloc (i, sizeof (char *));
/* Record which files were specified explicitly as link input. */
explicit_link_files = xcalloc (1, n_infiles);
+ if (combine_flag)
+ combine_inputs = true;
+ else
+ combine_inputs = false;
+
+ for (i = 0; (int) i < n_infiles; i++)
+ {
+ const char *name = infiles[i].name;
+ struct compiler *compiler = lookup_compiler (name,
+ strlen (name),
+ infiles[i].language);
+
+ if (compiler && !(compiler->combinable))
+ combine_inputs = false;
+
+ if (lang_n_infiles > 0 && compiler != input_file_compiler
+ && infiles[i].language && infiles[i].language[0] != '*')
+ infiles[i].incompiler = compiler;
+ else if (compiler)
+ {
+ lang_n_infiles++;
+ input_file_compiler = compiler;
+ infiles[i].incompiler = compiler;
+ }
+ else
+ {
+ /* Since there is no compiler for this input file, assume it is a
+ linker file. */
+ explicit_link_files[i] = 1;
+ infiles[i].incompiler = NULL;
+ }
+ infiles[i].compiled = false;
+ infiles[i].preprocessed = false;
+ }
+
+ if (combine_flag && save_temps_flag)
+ {
+ bool save_combine_inputs = combine_inputs;
+ /* Must do a separate pre-processing pass for C & Objective-C files, to
+ obtain individual .i files. */
+
+ combine_inputs = false;
+ for (i = 0; (int) i < n_infiles; i++)
+ {
+ int this_file_error = 0;
+
+ input_file_number = i;
+ set_input (infiles[i].name);
+ if (infiles[i].incompiler
+ && (infiles[i].incompiler)->needs_preprocessing)
+ input_file_compiler = infiles[i].incompiler;
+ else
+ continue;
+
+ if (input_file_compiler)
+ {
+ if (input_file_compiler->spec[0] == '#')
+ {
+ error ("%s: %s compiler not installed on this system",
+ input_filename, &input_file_compiler->spec[1]);
+ this_file_error = 1;
+ }
+ else
+ {
+ value = do_spec (input_file_compiler->spec);
+ infiles[i].preprocessed = true;
+ if (!have_o_argbuf_index)
+ fatal ("spec '%s' is invalid", input_file_compiler->spec);
+ infiles[i].name = argbuf[have_o_argbuf_index];
+ infiles[i].incompiler
+ = lookup_compiler (infiles[i].name,
+ strlen (infiles[i].name),
+ infiles[i].language);
+
+ if (value < 0)
+ this_file_error = 1;
+ }
+ }
+
+ if (this_file_error)
+ {
+ delete_failure_queue ();
+ error_count++;
+ break;
+ }
+ clear_failure_queue ();
+ }
+ combine_inputs = save_combine_inputs;
+ }
+
for (i = 0; (int) i < n_infiles; i++)
{
int this_file_error = 0;
input_file_number = i;
set_input (infiles[i].name);
+ if (infiles[i].compiled)
+ continue;
+
/* Use the same thing in %o, unless cp->spec says otherwise. */
outfiles[i] = input_filename;
/* Figure out which compiler from the file's suffix. */
- input_file_compiler
- = lookup_compiler (infiles[i].name, input_filename_length,
- infiles[i].language);
+ if (! combine_inputs)
+ input_file_compiler
+ = lookup_compiler (infiles[i].name, input_filename_length,
+ infiles[i].language);
+ else
+ input_file_compiler = infiles[i].incompiler;
if (input_file_compiler)
{
else
{
value = do_spec (input_file_compiler->spec);
+ infiles[i].compiled = true;
if (value < 0)
this_file_error = 1;
}
{
delete_failure_queue ();
error_count++;
+ break;
}
/* If this compilation succeeded, don't delete those files later. */
clear_failure_queue ();
or 0 if this file is to be passed to the linker. */
static struct compiler *
-lookup_compiler (name, length, language)
- const char *name;
- size_t length;
- const char *language;
+lookup_compiler (const char *name, size_t length, const char *language)
{
struct compiler *cp;
}
#if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
- /* look again, but case-insensitively this time. */
+ /* Look again, but case-insensitively this time. */
if (cp < compilers)
for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
{
}
\f
static char *
-save_string (s, len)
- const char *s;
- int len;
+save_string (const char *s, int len)
{
char *result = xmalloc (len + 1);
}
void
-pfatal_with_name (name)
- const char *name;
+pfatal_with_name (const char *name)
{
perror_with_name (name);
delete_temp_files ();
}
static void
-perror_with_name (name)
- const char *name;
+perror_with_name (const char *name)
{
error ("%s: %s", name, xstrerror (errno));
}
static void
-pfatal_pexecute (errmsg_fmt, errmsg_arg)
- const char *errmsg_fmt;
- const char *errmsg_arg;
+pfatal_pexecute (const char *errmsg_fmt, const char *errmsg_arg)
{
if (errmsg_arg)
{
pfatal_with_name (errmsg_fmt);
}
-/* Output an error message and exit */
+/* Output an error message and exit. */
void
-fancy_abort ()
+fancy_abort (const char *file, int line, const char *func)
{
- fatal ("internal gcc abort");
+ fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
}
\f
-/* Output an error message and exit */
+/* 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
-validate_switches_from_spec (spec)
- const char *spec;
+validate_switches_from_spec (const char *spec)
{
const char *p = spec;
char c;
}
static void
-validate_all_switches ()
+validate_all_switches (void)
{
struct compiler *comp;
struct spec_list *spec;
and mark as valid all supplied switches that match it. */
static const char *
-validate_switches (start)
- const char *start;
+validate_switches (const char *start)
{
const char *p = start;
const char *atom;
int i;
bool suffix = false;
bool starred = false;
-
+
#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
-
+
next_member:
SKIP_WHITE ();
canonicalize the switches to keep only the ones we care about. */
static int
-used_arg (p, len)
- const char *p;
- int len;
+used_arg (const char *p, int len)
{
struct mswitchstr
{
if (*q == ';')
cnt++;
- matches =
- (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
+ matches = alloca ((sizeof (struct mswitchstr)) * cnt);
i = 0;
q = multilib_matches;
while (*q != '\0')
while (*q != ' ')
{
if (*q == '\0')
- abort ();
+ {
+ invalid_matches:
+ fatal ("multilib spec '%s' is invalid", multilib_matches);
+ }
q++;
}
matches[i].len = q - matches[i].str;
while (*q != ';' && *q != '\0')
{
if (*q == ' ')
- abort ();
+ goto invalid_matches;
q++;
}
matches[i].rep_len = q - matches[i].replace;
xmalloc from calling fatal, and prevents us from re-executing this
block of code. */
mswitches
- = (struct mswitchstr *)
- xmalloc (sizeof (struct mswitchstr)
+ = xmalloc (sizeof (struct mswitchstr)
* (n_mdswitches + (n_switches ? n_switches : 1)));
for (i = 0; i < n_switches; i++)
- {
- int xlen = strlen (switches[i].part1);
- for (j = 0; j < cnt; j++)
- if (xlen == matches[j].len
- && ! strncmp (switches[i].part1, matches[j].str, xlen))
- {
- mswitches[n_mswitches].str = matches[j].replace;
- mswitches[n_mswitches].len = matches[j].rep_len;
- mswitches[n_mswitches].replace = (char *) 0;
- mswitches[n_mswitches].rep_len = 0;
- n_mswitches++;
- break;
- }
- }
+ if (switches[i].live_cond != SWITCH_IGNORE)
+ {
+ int xlen = strlen (switches[i].part1);
+ for (j = 0; j < cnt; j++)
+ if (xlen == matches[j].len
+ && ! strncmp (switches[i].part1, matches[j].str, xlen))
+ {
+ mswitches[n_mswitches].str = matches[j].replace;
+ mswitches[n_mswitches].len = matches[j].rep_len;
+ mswitches[n_mswitches].replace = (char *) 0;
+ mswitches[n_mswitches].rep_len = 0;
+ n_mswitches++;
+ break;
+ }
+ }
/* Add MULTILIB_DEFAULTS switches too, as long as they were not present
on the command line nor any options mutually incompatible with
}
static int
-default_arg (p, len)
- const char *p;
- int len;
+default_arg (const char *p, int len)
{
int i;
will be used. */
static void
-set_multilib_dir ()
+set_multilib_dir (void)
{
const char *p;
unsigned int this_path_len;
{
int i = 0;
- mdswitches
- = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr)
- * n_mdswitches);
+ mdswitches = xmalloc (sizeof (struct mdswitchstr) * n_mdswitches);
for (start = multilib_defaults; *start != '\0'; start = end + 1)
{
while (*start == ' ' || *start == '\t')
if (*start == '\0')
break;
-
+
for (end = start + 1;
*end != ' ' && *end != '\t' && *end != '\0'; end++)
;
while (*p != ';')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_exclusions:
+ fatal ("multilib exclusions '%s' is invalid",
+ multilib_exclusions);
+ }
if (! ok)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_exclusions;
++p;
}
while (*p != ' ')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_select:
+ fatal ("multilib select '%s' is invalid",
+ multilib_select);
+ }
++p;
}
this_path_len = p - this_path;
while (*p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (! ok)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
++p;
}
the exclusions. */
static void
-print_multilib_info ()
+print_multilib_info (void)
{
const char *p = multilib_select;
const char *last_path = 0, *this_path;
while (*p != ' ')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_select:
+ fatal ("multilib select '%s' is invalid", multilib_select);
+ }
+
++p;
}
int mp = 0;
if (*e == '\0')
- abort ();
+ {
+ invalid_exclusion:
+ fatal ("multilib exclusion '%s' is invalid",
+ multilib_exclusions);
+ }
if (! m)
{
while (*e != ' ' && *e != ';')
{
if (*e == '\0')
- abort ();
+ goto invalid_exclusion;
++e;
}
int len = e - this_arg;
if (*q == '\0')
- abort ();
+ goto invalid_select;
arg = q;
while (*q != ' ' && *q != ';')
{
if (*q == '\0')
- abort ();
+ goto invalid_select;
++q;
}
- if (! strncmp (arg, this_arg, (len < q - arg) ? q - arg : len) ||
- default_arg (this_arg, e - this_arg))
+ if (! strncmp (arg, this_arg,
+ (len < q - arg) ? q - arg : len)
+ || default_arg (this_arg, e - this_arg))
{
mp = 1;
break;
if (! skip)
{
/* If this is a duplicate, skip it. */
- skip = (last_path != 0 && (unsigned int) (p - this_path) == last_path_len
+ skip = (last_path != 0
+ && (unsigned int) (p - this_path) == last_path_len
&& ! strncmp (last_path, this_path, last_path_len));
last_path = this_path;
const char *arg;
if (*q == '\0')
- abort ();
+ goto invalid_select;
if (*q == '!')
arg = NULL;
while (*q != ' ' && *q != ';')
{
if (*q == '\0')
- abort ();
+ goto invalid_select;
++q;
}
int use_arg;
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (skip)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (use_arg)
putchar (*p);
++p;
(whose name has been expanded with %s). */
static const char *
-if_exists_spec_function (argc, argv)
- int argc;
- const char **argv;
+if_exists_spec_function (int argc, const char **argv)
{
/* Must have only one argument. */
- if (argc == 1 && IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
+ if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
return argv[0];
return NULL;
is returned if the first argument does not exist. */
static const char *
-if_exists_else_spec_function (argc, argv)
- int argc;
- const char **argv;
+if_exists_else_spec_function (int argc, const char **argv)
{
/* Must have exactly two arguments. */
if (argc != 2)
return NULL;
- if (IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
+ if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
return argv[0];
return argv[1];
}
+
+/* replace-outfile built-in spec function.
+ This looks for the first argument in the outfiles array's name and replaces it
+ with the second argument. */
+
+static const char *
+replace_outfile_spec_function (int argc, const char **argv)
+{
+ int i;
+ /* Must have exactly two arguments. */
+ if (argc != 2)
+ abort ();
+
+ for (i = 0; i < n_infiles; i++)
+ {
+ if (outfiles[i] && !strcmp (outfiles[i], argv[0]))
+ outfiles[i] = xstrdup (argv[1]);
+ }
+ return NULL;
+}
+