gcc.c 208 KB
Newer Older
Richard Stallman committed
1
/* Compiler driver program that can handle many languages.
Kazu Hirata committed
2
   Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Richard Stallman committed
4

5
This file is part of GCC.
Richard Stallman committed
6

7 8 9 10
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Richard Stallman committed
11

12 13 14 15
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
Richard Stallman committed
16 17

You should have received a copy of the GNU General Public License
18 19 20
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
Richard Stallman committed
21 22 23 24 25 26 27 28 29 30 31 32 33

This paragraph is here to try to keep Sun CC from dying.
The number of chars here seems crucial!!!!  */

/* This program is the user interface to the C compiler and possibly to
other compilers.  It is used because compilation is a complicated procedure
which involves running several programs and passing temporary files between
them, forwarding the users switches to those programs selectively,
and deleting the temporary files at the end.

CC recognizes how to compile each input file by suffixes in the file names.
Once it knows which kind of compilation to perform, the procedure for
compilation is specified by a string called a "spec".  */
Jeff Law committed
34

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/* A Short Introduction to Adding a Command-Line Option.

   Before adding a command-line option, consider if it is really
   necessary.  Each additional command-line option adds complexity and
   is difficult to remove in subsequent versions.

   In the following, consider adding the command-line argument
   `--bar'.

   1. Each command-line option is specified in the specs file.  The
   notation is described below in the comment entitled "The Specs
   Language".  Read it.

   2. In this file, add an entry to "option_map" equating the long
   `--' argument version and any shorter, single letter version.  Read
   the comments in the declaration of "struct option_map" for an
   explanation.  Do not omit the first `-'.

   3. Look in the "specs" file to determine which program or option
   list should be given the argument, e.g., "cc1_options".  Add the
   appropriate syntax for the shorter option version to the
   corresponding "const char *" entry in this file.  Omit the first
   `-' from the option.  For example, use `-bar', rather than `--bar'.

   4. If the argument takes an argument, e.g., `--baz argument1',
   modify either DEFAULT_SWITCH_TAKES_ARG or
   DEFAULT_WORD_SWITCH_TAKES_ARG in this file.  Omit the first `-'
   from `--baz'.

   5. Document the option in this file's display_help().  If the
   option is passed to a subprogram, modify its corresponding
   function, e.g., cppinit.c:print_help() or toplev.c:display_help(),
   instead.

   6. Compile and test.  Make sure that your new specs file is being
   read.  For example, use a debugger to investigate the value of
   "specs_file" in main().  */

73
#include "config.h"
74
#include "system.h"
75 76
#include "coretypes.h"
#include "tm.h"
77
#include <signal.h>
78 79 80
#if ! defined( SIGCHLD ) && defined( SIGCLD )
#  define SIGCHLD SIGCLD
#endif
81
#include "obstack.h"
82
#include "intl.h"
83
#include "prefix.h"
84
#include "gcc.h"
85
#include "flags.h"
86

87 88 89
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
90
#if defined (HAVE_DECL_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
91
extern int getrusage PARAMS ((int, struct rusage *));
92 93
#endif

94 95 96 97
/* By default there is no special suffix for target executables.  */
/* FIXME: when autoconf is fixed, remove the host check - dj */
#if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
#define HAVE_TARGET_EXECUTABLE_SUFFIX
Richard Stallman committed
98
#endif
99

100 101 102
/* By default there is no special suffix for host executables.  */
#ifdef HOST_EXECUTABLE_SUFFIX
#define HAVE_HOST_EXECUTABLE_SUFFIX
103
#else
104 105 106 107 108 109 110 111
#define HOST_EXECUTABLE_SUFFIX ""
#endif

/* By default, the suffix for target object files is ".o".  */
#ifdef TARGET_OBJECT_SUFFIX
#define HAVE_TARGET_OBJECT_SUFFIX
#else
#define TARGET_OBJECT_SUFFIX ".o"
112 113
#endif

Tom Tromey committed
114 115 116 117 118 119 120 121
#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 */

122
static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
123

124 125 126 127 128
/* Most every one is fine with LIBRARY_PATH.  For some, it conflicts.  */
#ifndef LIBRARY_PATH_ENV
#define LIBRARY_PATH_ENV "LIBRARY_PATH"
#endif

Jeff Law committed
129 130 131 132
#ifndef HAVE_KILL
#define kill(p,s) raise(s)
#endif

Richard Stallman committed
133 134 135 136 137
/* If a stage of compilation returns an exit status >= 1,
   compilation of that file ceases.  */

#define MIN_FATAL_STATUS 1

138 139 140
/* Flag set by cppspec.c to 1.  */
int is_cpp_driver;

Richard Kenner committed
141 142 143 144
/* Flag saying to pass the greatest exit code returned by a sub-process
   to the calling program.  */
static int pass_exit_codes;

145 146 147
/* Definition of string containing the arguments given to configure.  */
#include "configargs.h"

148 149 150 151 152
/* Flag saying to print the directories gcc will search through looking for
   programs, libraries, etc.  */

static int print_search_dirs;

153
/* Flag saying to print the full filename of this file
154 155
   as found through our usual search mechanism.  */

156
static const char *print_file_name = NULL;
157

Mike Stump committed
158
/* As print_file_name, but search for executable file.  */
159

160
static const char *print_prog_name = NULL;
161

Doug Evans committed
162 163 164 165 166
/* Flag saying to print the relative path we'd use to
   find libgcc.a given the current compiler flags.  */

static int print_multi_directory;

167 168 169 170 171
/* Flag saying to print the relative path we'd use to
   find OS libraries given the current compiler flags.  */

static int print_multi_os_directory;

Doug Evans committed
172 173 174 175 176
/* Flag saying to print the list of subdirectories and
   compiler flags used to select them in a standard form.  */

static int print_multi_lib;

Nick Clifton committed
177 178 179 180 181
/* Flag saying to print the command line options understood by gcc and its
   sub-processes.  */

static int print_help_list;

Richard Stallman committed
182 183 184 185
/* Flag indicating whether we should print the command and arguments */

static int verbose_flag;

186 187 188 189 190 191 192
/* Flag indicating whether we should ONLY print the command and
   arguments (like verbose_flag) without executing the command.
   Displayed arguments are quoted so that the generated command
   line is suitable for execution.  This is intended for use in
   shell scripts to capture the driver-generated command line.  */
static int verbose_only_flag;

193
/* Flag indicating to print target specific command line options.  */
194 195 196

static int target_help_flag;

197 198 199 200 201
/* Flag indicating whether we should report subprocess execution times
   (if this is supported by the system - see pexecute.c).  */

static int report_times;

202 203 204 205 206
/* Nonzero means place this string before uses of /, so that include
   and library files can be found in an alternate location.  */

static const char *target_system_root = TARGET_SYSTEM_ROOT;

Richard Stallman committed
207 208 209 210 211
/* 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;

212 213 214 215 216
/* Nonzero means use pipes to communicate between subprocesses.
   Overridden by either of the above two flags.  */

static int use_pipes;

217
/* The compiler version.  */
Richard Stallman committed
218

Zack Weinberg committed
219
static const char *compiler_version;
220 221 222

/* The target version specified with -V */

223
static const char *const spec_version = DEFAULT_TARGET_VERSION;
Richard Stallman committed
224 225 226

/* The target machine specified with -b.  */

227
static const char *spec_machine = DEFAULT_TARGET_MACHINE;
Richard Stallman committed
228

229 230 231 232
/* Nonzero if cross-compiling.
   When -b is used, the value comes from the `specs' file.  */

#ifdef CROSS_COMPILE
Zack Weinberg committed
233
static const char *cross_compile = "1";
234
#else
Zack Weinberg committed
235
static const char *cross_compile = "0";
236 237
#endif

238 239 240 241 242 243
#ifdef MODIFY_TARGET_NAME

/* Information on how to alter the target name based on a command-line
   switch.  The only case we support now is simply appending or deleting a
   string to or from the end of the first part of the configuration name.  */

244
static const struct modify_target
245
{
246 247 248
  const char *const sw;
  const enum add_del {ADD, DELETE} add_del;
  const char *const str;
249 250 251
}
modify_target[] = MODIFY_TARGET_NAME;
#endif
252

253
/* The number of errors that have occurred; the link phase will not be
254
   run if this is nonzero.  */
255 256
static int error_count = 0;

Richard Kenner committed
257 258 259 260
/* Greatest exit code of sub-processes that has been encountered up to
   now.  */
static int greatest_status = 1;

Richard Stallman committed
261 262 263 264
/* This is the obstack which we use to allocate many strings.  */

static struct obstack obstack;

265
/* This is the obstack to build an environment variable to pass to
266
   collect2 that describes all of the relevant switches of what to
267 268 269 270 271
   pass the compiler in building the list of pointers to constructors
   and destructors.  */

static struct obstack collect_obstack;

272 273 274 275 276 277
/* These structs are used to collect resource usage information for
   subprocesses.  */
#ifdef HAVE_GETRUSAGE
static struct rusage rus, prus;
#endif

Doug Evans committed
278 279 280
/* Forward declaration for prototypes.  */
struct path_prefix;

281
static void init_spec		PARAMS ((void));
Zack Weinberg committed
282 283
static void store_arg		PARAMS ((const char *, int, int));
static char *load_specs		PARAMS ((const char *));
284 285 286 287 288 289
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));
290 291
static char *find_a_file	PARAMS ((struct path_prefix *, const char *,
					 int, int));
292
static void add_prefix		PARAMS ((struct path_prefix *, const char *,
293
					 const char *, int, int, int *, int));
294 295
static void add_sysrooted_prefix PARAMS ((struct path_prefix *, const char *,
					  const char *, int, int, int *, int));
296
static void translate_options	PARAMS ((int *, const char *const **));
297 298 299 300 301 302 303
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 *));
304 305 306 307 308 309 310 311 312
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));
313 314 315
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 *));
316
static char *save_string	PARAMS ((const char *, int));
317
static void set_collect_gcc_options PARAMS ((void));
318
static int do_spec_1		PARAMS ((const char *, int, const char *));
319
static int do_spec_2		PARAMS ((const char *));
320
static void do_self_spec	PARAMS ((const char *));
321 322
static const char *find_file	PARAMS ((const char *));
static int is_directory		PARAMS ((const char *, const char *, int));
323
static const char *validate_switches	PARAMS ((const char *));
324
static void validate_all_switches PARAMS ((void));
325 326
static inline void validate_switches_from_spec PARAMS ((const char *));
static void give_switch		PARAMS ((int, int));
327 328 329 330 331 332
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 *))
333
  ATTRIBUTE_NORETURN;
334
static void notice		PARAMS ((const char *, ...))
335
  ATTRIBUTE_PRINTF_1;
336 337 338 339
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));
340
static void process_command		PARAMS ((int, const char *const *));
341
static int execute			PARAMS ((void));
342
static void alloc_args			PARAMS ((void));
343 344
static void clear_args			PARAMS ((void));
static void fatal_error			PARAMS ((int));
345
#ifdef ENABLE_SHARED_LIBGCC
346
static void init_gcc_specs              PARAMS ((struct obstack *,
347
						 const char *, const char *,
348
						 const char *));
349
#endif
350
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
351
static const char *convert_filename	PARAMS ((const char *, int, int));
352
#endif
353 354

static const char *if_exists_spec_function PARAMS ((int, const char **));
355
static const char *if_exists_else_spec_function PARAMS ((int, const char **));
Richard Stallman committed
356

357 358 359
/* The Specs Language

Specs are strings containing lines, each of which (if not blank)
Richard Stallman committed
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
is made up of a program name, and arguments separated by spaces.
The program name must be exact and start from root, since no path
is searched and it is unreliable to depend on the current working directory.
Redirection of input or output is not supported; the subprograms must
accept filenames saying what files to read and write.

In addition, the specs can contain %-sequences to substitute variable text
or for conditional text.  Here is a table of all defined %-sequences.
Note that spaces are not generated automatically around the results of
expanding these sequences; therefore, you can concatenate them together
or with constant text in a single argument.

 %%	substitute one % into the program name or argument.
 %i     substitute the name of the input file being processed.
 %b     substitute the basename of the input file being processed.
	This is the substring up to (and not including) the last period
	and not including the directory.
377
 %B	same as %b, but include the file suffix (text after the last period).
378 379 380 381 382 383 384
 %gSUFFIX
	substitute a file name that has suffix SUFFIX and is chosen
	once per compilation, and mark the argument a la %d.  To reduce
	exposure to denial-of-service attacks, the file name is now
	chosen in a way that is hard to predict even when previously
	chosen file names are known.  For example, `%g.s ... %g.o ... %g.s'
	might turn into `ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s'.  SUFFIX matches
385 386 387 388 389
	the regexp "[.A-Za-z]*%O"; "%O" is treated exactly as if it
	had been pre-processed.  Previously, %g was simply substituted
	with a file name chosen once per compilation, without regard
	to any appended suffix (which was therefore treated just like
	ordinary text), making such attacks more likely to succeed.
390 391 392 393 394 395
 %|SUFFIX
	like %g, but if -pipe is in effect, expands simply to "-".
 %mSUFFIX
        like %g, but if -pipe is in effect, expands to nothing.  (We have both
	%| and %m to accommodate differences between system assemblers; see
	the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
396 397 398 399 400 401 402 403 404 405 406 407
 %uSUFFIX
	like %g, but generates a new temporary file name even if %uSUFFIX
	was already seen.
 %USUFFIX
	substitutes the last file name generated with %uSUFFIX, generating a
	new one if there is no such last file name.  In the absence of any
	%uSUFFIX, this is just like %gSUFFIX, except they don't share
	the same suffix "space", so `%g.s ... %U.s ... %g.s ... %U.s'
	would involve the generation of two distinct file names, one
	for each `%g.s' and another for each `%U.s'.  Previously, %U was
	simply substituted with a file name chosen for the previous %u,
	without regard to any appended suffix.
408 409 410 411 412 413
 %jSUFFIX
        substitutes the name of the HOST_BIT_BUCKET, if any, and if it is
        writable, and if save-temps is off; otherwise, substitute the name
        of a temporary file, just like %u.  This temporary file is not
        meant for communication between processes, but rather as a junk
        disposal mechanism.
414 415 416 417
 %.SUFFIX
        substitutes .SUFFIX for the suffixes of a matched switch's args when
        it is subsequently output with %*. SUFFIX is terminated by the next
        space or %.
Richard Stallman committed
418 419 420 421 422 423
 %d	marks the argument containing or following the %d as a
	temporary file name, so that that file will be deleted if CC exits
	successfully.  Unlike %g, this contributes no text to the argument.
 %w	marks the argument containing or following the %w as the
	"output file" of this compilation.  This puts the argument
	into the sequence of arguments that %o will substitute later.
424
 %V	indicates that this compilation produces no "output file".
Richard Stallman committed
425 426 427 428 429 430 431 432 433 434
 %W{...}
	like %{...} but mark last argument supplied within
	as a file to be deleted on failure.
 %o	substitutes the names of all the output files, with spaces
	automatically placed around them.  You should write spaces
	around the %o as well or the results are undefined.
	%o is for use in the specs for running the linker.
	Input files whose names have no recognized suffix are not compiled
	at all, but they are included among the output files, so they will
	be linked.
435
 %O	substitutes the suffix for object files.  Note that this is
436 437 438 439 440 441 442
        handled specially when it immediately follows %g, %u, or %U
	(with or without a suffix argument) because of the need for
	those to form complete file names.  The handling is such that
	%O is treated exactly as if it had already been substituted,
	except that %g, %u, and %U do not currently support additional
	SUFFIX characters following %O as they would following, for
	example, `.o'.
Richard Stallman committed
443 444 445 446 447
 %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.
448
 %I	Substitute a -iprefix option made from GCC_EXEC_PREFIX.
Richard Stallman committed
449 450 451 452 453
 %s     current argument is the name of a library or startup file of some sort.
        Search for that file in a standard list of directories
	and substitute the full name found.
 %eSTR  Print STR as an error message.  STR is terminated by a newline.
        Use this when inconsistent options are detected.
454
 %nSTR  Print STR as a notice.  STR is terminated by a newline.
Richard Stallman committed
455 456
 %x{OPTION}	Accumulate an option for %X.
 %X	Output the accumulated linker options specified by compilations.
457
 %Y	Output the accumulated assembler options specified by compilations.
458
 %Z	Output the accumulated preprocessor options specified by compilations.
459
 %v1	Substitute the major version number of GCC.
460
	(For version 2.5.3, this is 2.)
461
 %v2	Substitute the minor version number of GCC.
462 463 464
	(For version 2.5.3, this is 5.)
 %v3	Substitute the patch level number of GCC.
	(For version 2.5.3, this is 3.)
Richard Stallman committed
465 466 467 468
 %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
	used here.  This can be used to run a post-processor after the
469
	assembler has done its job.
470
 %D	Dump out a -L option for each directory in startfile_prefixes.
Doug Evans committed
471
	If multilib_dir is set, extra entries are generated with it affixed.
Richard Stallman committed
472 473
 %l     process LINK_SPEC as a spec.
 %L     process LIB_SPEC as a spec.
Jason Merrill committed
474
 %G     process LIBGCC_SPEC as a spec.
475 476
 %M     output multilib_dir with directory separators replaced with "_";
	if multilib_dir is not set or is ".", output "".
Richard Stallman committed
477 478
 %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
 %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
479
 %C     process CPP_SPEC as a spec.
Richard Stallman committed
480 481 482 483 484
 %1	process CC1_SPEC as a spec.
 %2	process CC1PLUS_SPEC as a spec.
 %*	substitute the variable part of a matched option.  (See below.)
	Note that each comma in the substituted string is replaced by
	a single space.
485 486 487 488 489 490
 %<S    remove all occurrences of -S from the command line.
        Note - this command is position dependent.  % commands in the
        spec string before this one will see -S, % commands in the
        spec string after this one will not.
 %<S*	remove all occurrences of all switches beginning with -S from the
        command line.
491 492 493 494 495 496
 %:function(args)
	Call the named function FUNCTION, passing it ARGS.  ARGS is
	first processed as a nested spec string, then split into an
	argument vector in the usual fashion.  The function returns
	a string which is processed as if it had appeared literally
	as part of the current spec.
Richard Stallman committed
497 498 499 500
 %{S}   substitutes the -S switch, if that switch was given to CC.
	If that switch was not specified, this substitutes nothing.
	Here S is a metasyntactic variable.
 %{S*}  substitutes all the switches specified to CC whose names start
501
	with -S.  This is used for -o, -I, etc; switches that take
Richard Stallman committed
502 503 504
	arguments.  CC considers `-o foo' as being one switch whose
	name starts with `o'.  %{o*} would substitute this text,
	including the space; thus, two arguments would be generated.
505 506 507 508
 %{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*}.
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529

 %{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.
 %{S*:X}  substitutes X if one or more switches whose names start
          with -S was given to CC.  Normally X is substituted only
          once, no matter how many such switches appeared.  However,
          if %* appears somewhere in X, then X will be substituted
          once for each matching switch, with the %* replaced by the
          part of that switch that matched the '*'.
 %{.S:X}  substitutes X, if processing a file with suffix S.
 %{!.S:X} substitutes X, if NOT processing a file with suffix S.

 %{S|T:X} substitutes X if either -S or -T was given to CC.  This may be
	  combined with !, ., and * as above binding stronger than the OR.
	  If %* appears in X, all of the alternatives must be starred, and
	  only the first matching alternative is substituted.
 %{S:X;   if S was given to CC, substitutes X;
   T:Y;   else if T was given to CC, substitutes Y;
    :D}   else substitutes D.  There can be as many clauses as you need.
          This may be combined with ., !, |, and * as above.

530
 %(Spec) processes a specification defined in a specs file as *Spec:
531
 %[Spec] as above, but put __ around -D arguments
Richard Stallman committed
532

533
The conditional text X in a %{S:X} or similar construct may contain
Richard Stallman committed
534
other nested % constructs or spaces, or even newlines.  They are
535 536 537 538
processed as usual, as described above.  Trailing white space in X is
ignored.  White space may also appear anywhere on the left side of the
colon in these constructs, except between . or * and the corresponding
word.
Richard Stallman committed
539

540
The -O, -f, -m, and -W switches are handled specifically in these
541 542
constructs.  If another value of -O or the negated form of a -f, -m, or
-W switch is found later in the command line, the earlier switch
543 544
value is ignored, except with {S*} where S is just one letter; this
passes all matching options.
545

546 547 548
The character | at the beginning of the predicate text is used to indicate
that a command should be piped to the following command, but only if -pipe
is specified.
Richard Stallman committed
549 550 551 552 553 554 555 556 557 558 559 560 561

Note that it is built into CC which switches take arguments and which
do not.  You might think it would be useful to generalize this to
allow each compiler's spec to say which switches take arguments.  But
this cannot be done in a consistent fashion.  CC cannot even decide
which input files have been specified without knowing which switches
take arguments, and it must know which input files to compile in order
to tell which compilers to run.

CC also knows implicitly that arguments starting in `-l' are to be
treated as compiler output files, and passed to the linker in their
proper position among the other output files.  */

562
/* Define the macros used for specs %a, %l, %L, %S, %C, %1.  */
Richard Stallman committed
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601

/* config.h can define ASM_SPEC to provide extra args to the assembler
   or extra switch-translations.  */
#ifndef ASM_SPEC
#define ASM_SPEC ""
#endif

/* config.h can define ASM_FINAL_SPEC to run a post processor after
   the assembler has run.  */
#ifndef ASM_FINAL_SPEC
#define ASM_FINAL_SPEC ""
#endif

/* config.h can define CPP_SPEC to provide extra args to the C preprocessor
   or extra switch-translations.  */
#ifndef CPP_SPEC
#define CPP_SPEC ""
#endif

/* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
   or extra switch-translations.  */
#ifndef CC1_SPEC
#define CC1_SPEC ""
#endif

/* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
   or extra switch-translations.  */
#ifndef CC1PLUS_SPEC
#define CC1PLUS_SPEC ""
#endif

/* config.h can define LINK_SPEC to provide extra args to the linker
   or extra switch-translations.  */
#ifndef LINK_SPEC
#define LINK_SPEC ""
#endif

/* config.h can define LIB_SPEC to override the default libraries.  */
#ifndef LIB_SPEC
Jason Merrill committed
602 603 604 605 606 607 608 609
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#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)
/* Have gcc do the search for libgcc.a.  */
610
#define LIBGCC_SPEC "libgcc.a%s"
Jason Merrill committed
611
#else
612
#define LIBGCC_SPEC "-lgcc"
Jason Merrill committed
613
#endif
Richard Stallman committed
614 615 616 617 618
#endif

/* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
#ifndef STARTFILE_SPEC
#define STARTFILE_SPEC  \
619
  "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
Richard Stallman committed
620 621
#endif

622 623
/* config.h can define SWITCHES_NEED_SPACES to control which options
   require spaces between the option and the argument.  */
Richard Stallman committed
624 625 626 627 628 629 630 631 632
#ifndef SWITCHES_NEED_SPACES
#define SWITCHES_NEED_SPACES ""
#endif

/* config.h can define ENDFILE_SPEC to override the default crtn files.  */
#ifndef ENDFILE_SPEC
#define ENDFILE_SPEC ""
#endif

Bob Manson committed
633 634 635 636
#ifndef LINKER_NAME
#define LINKER_NAME "collect2"
#endif

637 638 639
/* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
   to the assembler.  */
#ifndef ASM_DEBUG_SPEC
640 641 642
# if defined(DBX_DEBUGGING_INFO) && defined(DWARF2_DEBUGGING_INFO) \
     && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
#  define ASM_DEBUG_SPEC					\
643 644 645
      (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG			\
       ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}"	\
       : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}")
646 647 648 649 650 651
# else
#  if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
#   define ASM_DEBUG_SPEC "%{g*:--gstabs}"
#  endif
#  if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
#   define ASM_DEBUG_SPEC "%{g*:--gdwarf2}"
652 653 654
#  endif
# endif
#endif
655 656 657
#ifndef ASM_DEBUG_SPEC
# define ASM_DEBUG_SPEC ""
#endif
658

659 660
/* Here is the spec for running the linker, after compiling all files.  */

661 662 663 664 665 666 667
/* This is overridable by the target in case they need to specify the
   -lgcc and -lc order specially, yet not require them to override all
   of LINK_COMMAND_SPEC.  */
#ifndef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
#endif

668 669 670 671 672 673 674 675 676 677 678
/* -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.  */
/* We want %{T*} after %{L*} and %D so that it can be used to specify linker
   scripts which exist in user specified directories, or in standard
   directories.  */
#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}}}\
679 680
    %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs:-lgcov}\
    %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
681 682 683 684 685 686 687 688 689 690 691 692 693
    %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif

#ifndef LINK_LIBGCC_SPEC
# ifdef LINK_LIBGCC_SPECIAL
/* Don't generate -L options for startfile prefix list.  */
#  define LINK_LIBGCC_SPEC ""
# else
/* Do generate them.  */
#  define LINK_LIBGCC_SPEC "%D"
# endif
#endif

694 695 696 697
#ifndef STARTFILE_PREFIX_SPEC
# define STARTFILE_PREFIX_SPEC ""
#endif

698
static const char *asm_debug;
Zack Weinberg committed
699 700 701 702
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;
703
static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
Zack Weinberg committed
704 705 706 707 708 709 710 711 712
static const char *asm_spec = ASM_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 *libgcc_spec = LIBGCC_SPEC;
static const char *endfile_spec = ENDFILE_SPEC;
static const char *startfile_spec = STARTFILE_SPEC;
static const char *switches_need_spaces = SWITCHES_NEED_SPACES;
static const char *linker_name_spec = LINKER_NAME;
713 714
static const char *link_command_spec = LINK_COMMAND_SPEC;
static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
715
static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
716 717 718 719 720 721 722

/* Standard options to cpp, cc1, and as, to reduce duplication in specs.
   There should be no need to override these in target dependent files,
   but we need to copy them to the specs file so that newer versions
   of the GCC driver can correctly drive older tool chains with the
   appropriate -B options.  */

723 724 725
/* When cpplib handles traditional preprocessing, get rid of this, and
   call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
   that we default the front end language better.  */
726
static const char *trad_capable_cpp =
727
"cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}";
728

729 730 731
/* We don't wrap .d files in %W{} since a missing .d file, and
   therefore no dependency entry, confuses make into thinking a .o
   file that happens to exist is up-to-date.  */
732
static const char *cpp_unique_options =
733
"%{C:%{!E:%eGNU C does not support -C without using -E}}\
734
 %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
735
 %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
736 737 738
 %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
 %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
 %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
739
 %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
740
 %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
741
 %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
742
 %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
743
 %{E|M|MM:%W{o*}}";
744 745

/* This contains cpp options which are common with cc1_options and are passed
Chris Demetriou committed
746 747 748 749
   only when preprocessing only to avoid duplication.  We pass the cc1 spec
   options to the preprocessor so that it the cc1 spec may manipulate
   options used to set target flags.  Those special target flags settings may
   in turn cause preprocessor symbols to be defined specially.  */
750
static const char *cpp_options =
751
"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
752
 %{O*} %{undef}";
753

754 755 756 757
/* This contains cpp options which are not passed when the preprocessor
   output will be used by another program.  */
static const char *cpp_debug_options = "%{d*}";

758
/* NB: This is shared amongst all front-ends.  */
759 760 761
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*}\
762
 -auxbase%{c|S:%{o*:-strip %*}%{!o*: %b}}%{!c:%{!S: %b}}\
763
 %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
Neil Booth committed
764
 %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
765
 %{Qn:-fno-ident} %{--help:--help}\
766
 %{--target-help:--target-help}\
767
 %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
768
 %{fsyntax-only:-o %j} %{-param*}";
769 770 771

static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
772

773
static const char *invoke_as =
774 775 776 777 778
#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
"%{!S:-o %|.s |\n as %(asm_options) %|.s %A }";
#else
"%{!S:-o %|.s |\n as %(asm_options) %m.s %A }";
#endif
779

780
/* Some compilers have limits on line lengths, and the multilib_select
781 782
   and/or multilib_matches strings can be very long, so we build them at
   run time.  */
783
static struct obstack multilib_obstack;
Zack Weinberg committed
784 785 786 787
static const char *multilib_select;
static const char *multilib_matches;
static const char *multilib_defaults;
static const char *multilib_exclusions;
788 789 790 791 792 793 794 795
#include "multilib.h"

/* Check whether a particular argument is a default argument.  */

#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "" }
#endif

Kazu Hirata committed
796
static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
Richard Stallman committed
797

798 799 800 801 802 803
#ifndef DRIVER_SELF_SPECS
#define DRIVER_SELF_SPECS ""
#endif

static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };

804 805
struct user_specs
{
Michael Meissner committed
806
  struct user_specs *next;
807
  const char *filename;
Michael Meissner committed
808 809 810 811
};

static struct user_specs *user_specs_head, *user_specs_tail;

Richard Stallman committed
812 813
/* This defines which switch letters take arguments.  */

814
#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
Richard Stallman committed
815 816
  ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
   || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
817
   || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
818
   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'B' || (CHAR) == 'b')
819 820 821

#ifndef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
Richard Stallman committed
822 823 824 825
#endif

/* This defines which multi-letter switches take arguments.  */

826
#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR)		\
827 828
 (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext")	\
  || !strcmp (STR, "Tbss") || !strcmp (STR, "include")	\
829 830
  || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
  || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
831
  || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
832 833
  || !strcmp (STR, "isystem") || !strcmp (STR, "-param") \
  || !strcmp (STR, "specs") \
Neil Booth committed
834
  || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ"))
835 836 837

#ifndef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
Richard Stallman committed
838 839
#endif

840
#ifdef HAVE_TARGET_EXECUTABLE_SUFFIX
841 842 843 844 845 846 847 848 849 850
/* This defines which switches stop a full compilation.  */
#define DEFAULT_SWITCH_CURTAILS_COMPILATION(CHAR) \
  ((CHAR) == 'c' || (CHAR) == 'S')

#ifndef SWITCH_CURTAILS_COMPILATION
#define SWITCH_CURTAILS_COMPILATION(CHAR) \
  DEFAULT_SWITCH_CURTAILS_COMPILATION(CHAR)
#endif
#endif

Richard Stallman committed
851 852 853 854
/* Record the mapping from file suffixes for compilation specs.  */

struct compiler
{
855
  const char *suffix;		/* Use this compiler for input files
Richard Stallman committed
856
				   whose names end in this suffix.  */
857

858
  const char *spec;		/* To use this compiler, run this spec.  */
859 860 861 862

  const char *cpp_spec;         /* If non-NULL, substitute this spec
				   for `%C', rather than the usual
				   cpp_spec.  */
Richard Stallman committed
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
};

/* Pointer to a vector of `struct compiler' that gives the spec for
   compiling a file, based on its suffix.
   A file that does not end in any of these suffixes will be passed
   unchanged to the loader and nothing else will be done to it.

   An entry containing two 0s is used to terminate the vector.

   If multiple entries match a file, the last matching one is used.  */

static struct compiler *compilers;

/* Number of entries in `compilers', not counting the null terminator.  */

static int n_compilers;

/* The default list of file name suffixes and their compilation specs.  */

882
static const struct compiler default_compilers[] =
Richard Stallman committed
883
{
884
  /* Add lists of suffixes of known languages here.  If those languages
885 886
     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
887
     linking is not done".  */
888 889 890
  {".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},
891
  {".CPP", "#C++", 0}, {".ii", "#C++", 0},
892
  {".ads", "#Ada", 0}, {".adb", "#Ada", 0},
893 894 895 896 897 898
  {".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},
899
  /* Next come the entries for C.  */
900
  {".c", "@c", 0},
Richard Stallman committed
901
  {"@c",
902
   /* cc1 has an integrated ISO C preprocessor.  We should invoke the
903
      external preprocessor if -save-temps is given.  */
904
     "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
905
      %{!E:%{!M:%{!MM:\
906 907 908
          %{traditional|ftraditional:\
%eGNU C no longer supports -traditional without -E}\
	  %{save-temps|traditional-cpp:%(trad_capable_cpp) \
909
		%(cpp_options) %b.i \n\
910
		    cc1 -fpreprocessed %b.i %(cc1_options)}\
911
	  %{!save-temps:%{!traditional-cpp:\
912
		cc1 %(cpp_unique_options) %(cc1_options)}}\
913
        %{!fsyntax-only:%(invoke_as)}}}}", 0},
Richard Stallman committed
914
  {"-",
915
   "%{!E:%e-E required when input is from standard input}\
916
    %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
917
  {".h", "@c-header", 0},
Richard Stallman committed
918
  {"@c-header",
919 920 921 922 923 924 925 926 927 928 929 930 931
   /* 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}\
                        %W{o*:--output-pch=%*}%V}\
	  %{!save-temps:%{!traditional-cpp:\
		cc1 %(cpp_unique_options) %(cc1_options)\
                    -o %g.s %{!o*:--output-pch=%i.pch}\
                    %W{o*:--output-pch=%*}%V}}}}}", 0},
932
  {".i", "@cpp-output", 0},
Richard Stallman committed
933
  {"@cpp-output",
934 935
   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
  {".s", "@assembler", 0},
Richard Stallman committed
936
  {"@assembler",
937
   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0},
938
  {".S", "@assembler-with-cpp", 0},
Richard Stallman committed
939
  {"@assembler-with-cpp",
940
#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
941
   "%(trad_capable_cpp) -lang-asm %(cpp_options)\
942
      %{E|M|MM:%(cpp_debug_options)}\
943 944 945 946 947 948 949 950 951 952
      %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
       as %(asm_debug) %(asm_options) %|.s %A }}}}"
#else
   "%(trad_capable_cpp) -lang-asm %(cpp_options)\
      %{E|M|MM:%(cpp_debug_options)}\
      %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
       as %(asm_debug) %(asm_options) %m.s %A }}}}"
#endif
   , 0},
  
953
#include "specs.h"
Richard Stallman committed
954
  /* Mark end of table */
955
  {0, 0, 0}
Richard Stallman committed
956 957 958 959
};

/* Number of elements in default_compilers, not counting the terminator.  */

960
static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
Richard Stallman committed
961 962

/* A vector of options to give to the linker.
963
   These options are accumulated by %x,
Richard Stallman committed
964 965 966
   and substituted into the linker command with %X.  */
static int n_linker_options;
static char **linker_options;
967 968 969

/* A vector of options to give to the assembler.
   These options are accumulated by -Wa,
970
   and substituted into the assembler command with %Y.  */
971 972
static int n_assembler_options;
static char **assembler_options;
973 974 975 976 977 978

/* A vector of options to give to the preprocessor.
   These options are accumulated by -Wp,
   and substituted into the preprocessor command with %Z.  */
static int n_preprocessor_options;
static char **preprocessor_options;
Richard Stallman committed
979

980 981 982 983 984 985
/* Define how to map long options into short ones.  */

/* This structure describes one mapping.  */
struct option_map
{
  /* The long option's name.  */
986
  const char *const name;
987
  /* The equivalent short option.  */
988
  const char *const equivalent;
989 990 991 992
  /* Argument info.  A string of flag chars; NULL equals no options.
     a => argument required.
     o => argument optional.
     j => join argument to equivalent, making one word.
993
     * => require other text after NAME as an argument.  */
994
  const char *const arg_info;
995 996 997 998 999
};

/* This is the table of mappings.  Mappings are tried sequentially
   for each option encountered; the first one that matches, wins.  */

1000
static const struct option_map option_map[] =
1001
 {
1002 1003 1004 1005
   {"--all-warnings", "-Wall", 0},
   {"--ansi", "-ansi", 0},
   {"--assemble", "-S", 0},
   {"--assert", "-A", "a"},
1006
   {"--classpath", "-fclasspath=", "aj"},
1007 1008
   {"--bootclasspath", "-fbootclasspath=", "aj"},
   {"--CLASSPATH", "-fclasspath=", "aj"},
1009
   {"--comments", "-C", 0},
1010
   {"--comments-in-macros", "-CC", 0},
1011
   {"--compile", "-c", 0},
1012
   {"--debug", "-g", "oj"},
1013
   {"--define-macro", "-D", "aj"},
1014
   {"--dependencies", "-M", 0},
1015
   {"--dump", "-d", "a"},
1016
   {"--dumpbase", "-dumpbase", "a"},
1017
   {"--entry", "-e", 0},
1018 1019 1020 1021
   {"--extra-warnings", "-W", 0},
   {"--for-assembler", "-Wa", "a"},
   {"--for-linker", "-Xlinker", "a"},
   {"--force-link", "-u", "a"},
1022
   {"--imacros", "-imacros", "a"},
1023 1024
   {"--include", "-include", "a"},
   {"--include-barrier", "-I-", 0},
1025
   {"--include-directory", "-I", "aj"},
1026
   {"--include-directory-after", "-idirafter", "a"},
1027
   {"--include-prefix", "-iprefix", "a"},
1028
   {"--include-with-prefix", "-iwithprefix", "a"},
1029 1030
   {"--include-with-prefix-before", "-iwithprefixbefore", "a"},
   {"--include-with-prefix-after", "-iwithprefix", "a"},
1031 1032
   {"--language", "-x", "a"},
   {"--library-directory", "-L", "a"},
1033
   {"--machine", "-m", "aj"},
1034 1035 1036
   {"--machine-", "-m", "*j"},
   {"--no-line-commands", "-P", 0},
   {"--no-precompiled-includes", "-noprecomp", 0},
1037 1038 1039 1040
   {"--no-standard-includes", "-nostdinc", 0},
   {"--no-standard-libraries", "-nostdlib", 0},
   {"--no-warnings", "-w", 0},
   {"--optimize", "-O", "oj"},
1041
   {"--output", "-o", "a"},
1042
   {"--output-class-directory", "-foutput-class-dir=", "ja"},
1043
   {"--param", "--param", "a"},
1044 1045
   {"--pedantic", "-pedantic", 0},
   {"--pedantic-errors", "-pedantic-errors", 0},
1046 1047 1048
   {"--pipe", "-pipe", 0},
   {"--prefix", "-B", "a"},
   {"--preprocess", "-E", 0},
1049
   {"--print-search-dirs", "-print-search-dirs", 0},
1050
   {"--print-file-name", "-print-file-name=", "aj"},
1051 1052
   {"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
   {"--print-missing-file-dependencies", "-MG", 0},
Doug Evans committed
1053 1054
   {"--print-multi-lib", "-print-multi-lib", 0},
   {"--print-multi-directory", "-print-multi-directory", 0},
1055
   {"--print-multi-os-directory", "-print-multi-os-directory", 0},
1056 1057 1058 1059
   {"--print-prog-name", "-print-prog-name=", "aj"},
   {"--profile", "-p", 0},
   {"--profile-blocks", "-a", 0},
   {"--quiet", "-q", 0},
1060
   {"--resource", "-fcompile-resource=", "aj"},
1061
   {"--save-temps", "-save-temps", 0},
1062
   {"--shared", "-shared", 0},
1063
   {"--silent", "-q", 0},
Michael Meissner committed
1064
   {"--specs", "-specs=", "aj"},
1065
   {"--static", "-static", 0},
1066
   {"--std", "-std=", "aj"},
1067
   {"--symbolic", "-symbolic", 0},
1068
   {"--target", "-b", "a"},
1069
   {"--time", "-time", 0},
1070 1071 1072 1073
   {"--trace-includes", "-H", 0},
   {"--traditional", "-traditional", 0},
   {"--traditional-cpp", "-traditional-cpp", 0},
   {"--trigraphs", "-trigraphs", 0},
1074
   {"--undefine-macro", "-U", "aj"},
1075 1076 1077 1078 1079 1080
   {"--use-version", "-V", "a"},
   {"--user-dependencies", "-MM", 0},
   {"--verbose", "-v", 0},
   {"--warn-", "-W", "*j"},
   {"--write-dependencies", "-MD", 0},
   {"--write-user-dependencies", "-MMD", 0},
1081 1082 1083
   {"--", "-f", "*j"}
 };

1084 1085

#ifdef TARGET_OPTION_TRANSLATE_TABLE
1086 1087 1088
static const struct {
  const char *const option_found;
  const char *const replacements;
1089 1090 1091 1092 1093 1094 1095
} target_option_translations[] =
{
  TARGET_OPTION_TRANSLATE_TABLE,
  { 0, 0 }
};
#endif

1096 1097 1098 1099 1100 1101 1102
/* Translate the options described by *ARGCP and *ARGVP.
   Make a new vector and store it back in *ARGVP,
   and store its length in *ARGVC.  */

static void
translate_options (argcp, argvp)
     int *argcp;
1103
     const char *const **argvp;
1104
{
Kaveh R. Ghazi committed
1105
  int i;
1106
  int argc = *argcp;
1107
  const char *const *argv = *argvp;
1108
  int newvsize = (argc + 2) * 2 * sizeof (const char *);
1109
  const char **newv =
1110
    (const char **) xmalloc (newvsize);
1111 1112 1113 1114 1115 1116 1117
  int newindex = 0;

  i = 0;
  newv[newindex++] = argv[i++];

  while (i < argc)
    {
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
#ifdef TARGET_OPTION_TRANSLATE_TABLE
      int tott_idx;

      for (tott_idx = 0;
	   target_option_translations[tott_idx].option_found;
	   tott_idx++)
	{
	  if (strcmp (target_option_translations[tott_idx].option_found,
		      argv[i]) == 0)
	    {
	      int spaces = 1;
	      const char *sp;
	      char *np;

	      for (sp = target_option_translations[tott_idx].replacements;
		   *sp; sp++)
		{
		  if (*sp == ' ')
		    spaces ++;
		}

	      newvsize += spaces * sizeof (const char *);
	      newv = (const char **) xrealloc (newv, newvsize);

	      sp = target_option_translations[tott_idx].replacements;
1143
	      np = xstrdup (sp);
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166

	      while (1)
		{
		  while (*np == ' ')
		    np++;
		  if (*np == 0)
		    break;
		  newv[newindex++] = np;
		  while (*np != ' ' && *np)
		    np++;
		  if (*np == 0)
		    break;
		  *np++ = 0;
		}

	      i ++;
	      break;
	    }
	}
      if (target_option_translations[tott_idx].option_found)
	continue;
#endif

1167 1168 1169
      /* Translate -- options.  */
      if (argv[i][0] == '-' && argv[i][1] == '-')
	{
Kaveh R. Ghazi committed
1170
	  size_t j;
1171
	  /* Find a mapping that applies to this option.  */
1172
	  for (j = 0; j < ARRAY_SIZE (option_map); j++)
1173
	    {
1174 1175 1176
	      size_t optlen = strlen (option_map[j].name);
	      size_t arglen = strlen (argv[i]);
	      size_t complen = arglen > optlen ? optlen : arglen;
1177
	      const char *arginfo = option_map[j].arg_info;
1178 1179 1180

	      if (arginfo == 0)
		arginfo = "";
1181

1182 1183
	      if (!strncmp (argv[i], option_map[j].name, complen))
		{
1184
		  const char *arg = 0;
1185

1186 1187
		  if (arglen < optlen)
		    {
Kaveh R. Ghazi committed
1188
		      size_t k;
1189
		      for (k = j + 1; k < ARRAY_SIZE (option_map); k++)
1190 1191 1192
			if (strlen (option_map[k].name) >= arglen
			    && !strncmp (argv[i], option_map[k].name, arglen))
			  {
1193
			    error ("ambiguous abbreviation %s", argv[i]);
1194 1195 1196
			    break;
			  }

1197
		      if (k != ARRAY_SIZE (option_map))
1198 1199 1200 1201
			break;
		    }

		  if (arglen > optlen)
1202 1203 1204 1205
		    {
		      /* If the option has an argument, accept that.  */
		      if (argv[i][optlen] == '=')
			arg = argv[i] + optlen + 1;
1206 1207

		      /* If this mapping requires extra text at end of name,
1208
			 accept that as "argument".  */
1209
		      else if (strchr (arginfo, '*') != 0)
1210
			arg = argv[i] + optlen;
1211

1212 1213 1214 1215 1216
		      /* Otherwise, extra text at end means mismatch.
			 Try other mappings.  */
		      else
			continue;
		    }
1217

1218
		  else if (strchr (arginfo, '*') != 0)
1219
		    {
1220
		      error ("incomplete `%s' option", option_map[j].name);
1221 1222
		      break;
		    }
1223 1224

		  /* Handle arguments.  */
1225
		  if (strchr (arginfo, 'a') != 0)
1226 1227 1228 1229
		    {
		      if (arg == 0)
			{
			  if (i + 1 == argc)
1230
			    {
1231
			      error ("missing argument to `%s' option",
1232 1233 1234 1235
				     option_map[j].name);
			      break;
			    }

1236 1237 1238
			  arg = argv[++i];
			}
		    }
1239
		  else if (strchr (arginfo, '*') != 0)
1240
		    ;
1241
		  else if (strchr (arginfo, 'o') == 0)
1242 1243
		    {
		      if (arg != 0)
1244
			error ("extraneous argument to `%s' option",
1245 1246 1247 1248 1249
			       option_map[j].name);
		      arg = 0;
		    }

		  /* Store the translation as one argv elt or as two.  */
1250
		  if (arg != 0 && strchr (arginfo, 'j') != 0)
1251
		    newv[newindex++] = concat (option_map[j].equivalent, arg,
1252
					       NULL);
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
		  else if (arg != 0)
		    {
		      newv[newindex++] = option_map[j].equivalent;
		      newv[newindex++] = arg;
		    }
		  else
		    newv[newindex++] = option_map[j].equivalent;

		  break;
		}
	    }
	  i++;
	}
1266

1267 1268 1269 1270
      /* Handle old-fashioned options--just copy them through,
	 with their arguments.  */
      else if (argv[i][0] == '-')
	{
1271
	  const char *p = argv[i] + 1;
1272 1273 1274 1275 1276 1277 1278
	  int c = *p;
	  int nskip = 1;

	  if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
	    nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
	  else if (WORD_SWITCH_TAKES_ARG (p))
	    nskip += WORD_SWITCH_TAKES_ARG (p);
1279
	  else if ((c == 'B' || c == 'b' || c == 'x')
1280 1281 1282 1283
		   && p[1] == 0)
	    nskip += 1;
	  else if (! strcmp (p, "Xlinker"))
	    nskip += 1;
1284 1285 1286 1287
	  else if (! strcmp (p, "Xpreprocessor"))
	    nskip += 1;
	  else if (! strcmp (p, "Xassembler"))
	    nskip += 1;
1288

1289 1290 1291 1292 1293 1294
	  /* Watch out for an option at the end of the command line that
	     is missing arguments, and avoid skipping past the end of the
	     command line.  */
	  if (nskip + i > argc)
	    nskip = argc - i;

1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
	  while (nskip > 0)
	    {
	      newv[newindex++] = argv[i++];
	      nskip--;
	    }
	}
      else
	/* Ordinary operands, or +e options.  */
	newv[newindex++] = argv[i++];
    }

  newv[newindex] = 0;

  *argvp = newv;
  *argcp = newindex;
}

Richard Stallman committed
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
static char *
skip_whitespace (p)
     char *p;
{
  while (1)
    {
      /* A fully-blank line is a delimiter in the SPEC file and shouldn't
	 be considered whitespace.  */
      if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
	return p + 1;
      else if (*p == '\n' || *p == ' ' || *p == '\t')
	p++;
      else if (*p == '#')
	{
Kazu Hirata committed
1326 1327
	  while (*p != '\n')
	    p++;
Richard Stallman committed
1328 1329 1330 1331 1332 1333 1334 1335
	  p++;
	}
      else
	break;
    }

  return p;
}
1336 1337 1338 1339
/* Structures to keep track of prefixes to try when looking for files.  */

struct prefix_list
{
1340
  const char *prefix;	      /* String to prepend to the path.  */
1341 1342 1343 1344
  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.  */
1345 1346 1347
  int priority;		      /* Sort key - priority within list.  */
  int os_multilib;	      /* 1 if OS multilib scheme should be used,
				 0 for GCC multilib scheme.  */
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
};

struct path_prefix
{
  struct prefix_list *plist;  /* List of prefixes to try */
  int max_len;                /* Max length of a prefix in PLIST */
  const char *name;           /* Name of this list (used in config stuff) */
};

/* List of prefixes to try when looking for executables.  */

static struct path_prefix exec_prefixes = { 0, 0, "exec" };

/* List of prefixes to try when looking for startup (crt0) files.  */

static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };

/* List of prefixes to try when looking for include files.  */

static struct path_prefix include_prefixes = { 0, 0, "include" };

/* Suffix to attach to directories searched for commands.
   This looks like `MACHINE/VERSION/'.  */

static const char *machine_suffix = 0;

/* Suffix to attach to directories searched for commands.
   This is just `MACHINE/'.  */

static const char *just_machine_suffix = 0;

/* Adjusted value of GCC_EXEC_PREFIX envvar.  */

static const char *gcc_exec_prefix;

/* Default prefixes to attach to command names.  */

#ifdef CROSS_COMPILE  /* Don't use these prefixes for a cross compiler.  */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
#undef MD_STARTFILE_PREFIX_1
#endif

/* If no prefixes defined, use the null string, which will disable them.  */
#ifndef MD_EXEC_PREFIX
#define MD_EXEC_PREFIX ""
#endif
#ifndef MD_STARTFILE_PREFIX
#define MD_STARTFILE_PREFIX ""
#endif
#ifndef MD_STARTFILE_PREFIX_1
#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

1417 1418
static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
static const char *const standard_exec_prefix_1 = "/usr/lib/gcc/";
1419 1420 1421 1422
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;
1423 1424 1425
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/";
1426

1427
static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
1428 1429
static const char *tooldir_prefix;

1430
static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
1431 1432 1433 1434 1435

/* Subdirectory to use for locating libraries.  Set by
   set_multilib_dir based on the compilation options.  */

static const char *multilib_dir;
1436 1437 1438 1439 1440

/* Subdirectory to use for locating libraries in OS conventions.  Set by
   set_multilib_dir based on the compilation options.  */

static const char *multilib_os_dir;
Richard Stallman committed
1441

Mike Stump committed
1442
/* Structure to keep track of the specs that have been defined so far.
1443 1444
   These are accessed using %(specname) or %[specname] in a compiler
   or link spec.  */
Richard Stallman committed
1445 1446 1447

struct spec_list
{
Michael Meissner committed
1448 1449
				/* The following 2 fields must be first */
				/* to allow EXTRA_SPECS to be initialized */
Zack Weinberg committed
1450 1451
  const char *name;		/* name of the spec.  */
  const char *ptr;		/* available ptr if no static pointer */
Michael Meissner committed
1452 1453 1454

				/* The following fields are not initialized */
				/* by EXTRA_SPECS */
Zack Weinberg committed
1455
  const char **ptr_spec;	/* pointer to the spec itself.  */
Michael Meissner committed
1456 1457 1458
  struct spec_list *next;	/* Next spec in linked list.  */
  int name_len;			/* length of the name */
  int alloc_p;			/* whether string was allocated */
Richard Stallman committed
1459 1460
};

Michael Meissner committed
1461
#define INIT_STATIC_SPEC(NAME,PTR) \
1462
{ NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, 0 }
Michael Meissner committed
1463

1464 1465 1466
/* List of statically defined specs.  */
static struct spec_list static_specs[] =
{
Michael Meissner committed
1467
  INIT_STATIC_SPEC ("asm",			&asm_spec),
1468
  INIT_STATIC_SPEC ("asm_debug",		&asm_debug),
Michael Meissner committed
1469
  INIT_STATIC_SPEC ("asm_final",		&asm_final_spec),
1470
  INIT_STATIC_SPEC ("asm_options",		&asm_options),
1471
  INIT_STATIC_SPEC ("invoke_as",		&invoke_as),
Michael Meissner committed
1472
  INIT_STATIC_SPEC ("cpp",			&cpp_spec),
1473
  INIT_STATIC_SPEC ("cpp_options",		&cpp_options),
1474
  INIT_STATIC_SPEC ("cpp_debug_options",	&cpp_debug_options),
1475
  INIT_STATIC_SPEC ("cpp_unique_options",	&cpp_unique_options),
1476
  INIT_STATIC_SPEC ("trad_capable_cpp",		&trad_capable_cpp),
Michael Meissner committed
1477
  INIT_STATIC_SPEC ("cc1",			&cc1_spec),
1478
  INIT_STATIC_SPEC ("cc1_options",		&cc1_options),
Michael Meissner committed
1479
  INIT_STATIC_SPEC ("cc1plus",			&cc1plus_spec),
1480
  INIT_STATIC_SPEC ("link_gcc_c_sequence",	&link_gcc_c_sequence_spec),
Michael Meissner committed
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493
  INIT_STATIC_SPEC ("endfile",			&endfile_spec),
  INIT_STATIC_SPEC ("link",			&link_spec),
  INIT_STATIC_SPEC ("lib",			&lib_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 ("multilib_defaults",	&multilib_defaults),
  INIT_STATIC_SPEC ("multilib_extra",		&multilib_extra),
  INIT_STATIC_SPEC ("multilib_matches",		&multilib_matches),
1494
  INIT_STATIC_SPEC ("multilib_exclusions",	&multilib_exclusions),
1495
  INIT_STATIC_SPEC ("multilib_options",		&multilib_options),
Bob Manson committed
1496
  INIT_STATIC_SPEC ("linker",			&linker_name_spec),
1497
  INIT_STATIC_SPEC ("link_libgcc",		&link_libgcc_spec),
1498 1499 1500
  INIT_STATIC_SPEC ("md_exec_prefix",		&md_exec_prefix),
  INIT_STATIC_SPEC ("md_startfile_prefix",	&md_startfile_prefix),
  INIT_STATIC_SPEC ("md_startfile_prefix_1",	&md_startfile_prefix_1),
1501
  INIT_STATIC_SPEC ("startfile_prefix_spec",	&startfile_prefix_spec),
Michael Meissner committed
1502 1503 1504
};

#ifdef EXTRA_SPECS		/* additional specs needed */
Kaveh R. Ghazi committed
1505
/* Structure to keep track of just the first two args of a spec_list.
1506
   That is all that the EXTRA_SPECS macro gives us.  */
Kaveh R. Ghazi committed
1507 1508
struct spec_list_1
{
1509 1510
  const char *const name;
  const char *const ptr;
Kaveh R. Ghazi committed
1511 1512
};

1513
static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
Kazu Hirata committed
1514
static struct spec_list *extra_specs = (struct spec_list *) 0;
Michael Meissner committed
1515 1516 1517 1518
#endif

/* List of dynamically allocates specs that have been defined so far.  */

Kazu Hirata committed
1519
static struct spec_list *specs = (struct spec_list *) 0;
Michael Meissner committed
1520

1521 1522 1523 1524 1525
/* List of static spec functions.  */

static const struct spec_function static_spec_functions[] =
{
  { "if-exists",		if_exists_spec_function },
1526
  { "if-exists-else",		if_exists_else_spec_function },
1527 1528 1529 1530 1531
  { 0, 0 }
};

static int processing_spec_function;

1532 1533 1534
/* Add appropriate libgcc specs to OBSTACK, taking into account
   various permutations of -shared-libgcc, -shared, and such.  */

1535
#ifdef ENABLE_SHARED_LIBGCC
1536
static void
1537
init_gcc_specs (obstack, shared_name, static_name, eh_name)
1538 1539 1540
     struct obstack *obstack;
     const char *shared_name;
     const char *static_name;
1541
     const char *eh_name;
1542
{
1543 1544
  char *buf;

1545 1546 1547
  buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
		"}%{!static:%{!static-libgcc:",
		"%{!shared:%{!shared-libgcc:", static_name, " ",
1548
		eh_name, "}%{shared-libgcc:", shared_name, " ",
1549
		static_name, "}}%{shared:",
1550
#ifdef LINK_EH_SPEC
1551 1552
		"%{shared-libgcc:", shared_name,
		"}%{!shared-libgcc:", static_name, "}",
1553
#else
1554
		shared_name,
1555
#endif
1556
		"}}}", NULL);
1557 1558 1559

  obstack_grow (obstack, buf, strlen (buf));
  free (buf);
1560
}
1561
#endif /* ENABLE_SHARED_LIBGCC */
1562

Michael Meissner committed
1563 1564 1565
/* Initialize the specs lookup routines.  */

static void
1566
init_spec ()
Michael Meissner committed
1567
{
Kazu Hirata committed
1568 1569
  struct spec_list *next = (struct spec_list *) 0;
  struct spec_list *sl   = (struct spec_list *) 0;
Michael Meissner committed
1570 1571 1572
  int i;

  if (specs)
1573
    return;			/* Already initialized.  */
Michael Meissner committed
1574

1575
  if (verbose_flag)
1576
    notice ("Using built-in specs.\n");
1577

Michael Meissner committed
1578
#ifdef EXTRA_SPECS
Kaveh R. Ghazi committed
1579
  extra_specs = (struct spec_list *)
1580
    xcalloc (sizeof (struct spec_list), ARRAY_SIZE (extra_specs_1));
Kazu Hirata committed
1581

1582
  for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
1583 1584
    {
      sl = &extra_specs[i];
Kaveh R. Ghazi committed
1585 1586
      sl->name = extra_specs_1[i].name;
      sl->ptr = extra_specs_1[i].ptr;
1587 1588 1589 1590 1591
      sl->next = next;
      sl->name_len = strlen (sl->name);
      sl->ptr_spec = &sl->ptr;
      next = sl;
    }
Michael Meissner committed
1592 1593
#endif

1594 1595 1596 1597
  /* Initialize here, not in definition.  The IRIX 6 O32 cc sometimes chokes
     on ?: in file-scope variable initializations.  */
  asm_debug = ASM_DEBUG_SPEC;

1598
  for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
Michael Meissner committed
1599 1600 1601 1602 1603 1604
    {
      sl = &static_specs[i];
      sl->next = next;
      next = sl;
    }

1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618
#ifdef ENABLE_SHARED_LIBGCC
  /* ??? If neither -shared-libgcc nor --static-libgcc was
     seen, then we should be making an educated guess.  Some proposed
     heuristics for ELF include:

	(1) If "-Wl,--export-dynamic", then it's a fair bet that the
	    program will be doing dynamic loading, which will likely
	    need the shared libgcc.

	(2) If "-ldl", then it's also a fair bet that we're doing
	    dynamic loading.

	(3) For each ET_DYN we're linking against (either through -lfoo
	    or /some/path/foo.so), check to see whether it or one of
1619
	    its dependencies depends on a shared libgcc.
1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635

	(4) If "-shared"

	    If the runtime is fixed to look for program headers instead
	    of calling __register_frame_info at all, for each object,
	    use the shared libgcc if any EH symbol referenced.

	    If crtstuff is fixed to not invoke __register_frame_info
	    automatically, for each object, use the shared libgcc if
	    any non-empty unwind section found.

     Doing any of this probably requires invoking an external program to
     do the actual object file scanning.  */
  {
    const char *p = libgcc_spec;
    int in_sep = 1;
1636

1637
    /* Transform the extant libgcc_spec into one that uses the shared libgcc
1638 1639 1640
       when given the proper command line arguments.  */
    while (*p)
      {
1641
	if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
1642
	  {
1643
	    init_gcc_specs (&obstack,
1644
#ifdef NO_SHARED_LIBGCC_MULTILIB
1645
			    "-lgcc_s"
1646
#else
1647
			    "-lgcc_s%M"
1648
#endif
1649 1650 1651
#ifdef USE_LIBUNWIND_EXCEPTIONS
			    " -lunwind"
#endif
1652
			    ,
1653 1654
			    "-lgcc",
			    "-lgcc_eh");
1655
	    p += 5;
1656 1657
	    in_sep = 0;
	  }
1658
	else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
1659 1660 1661
	  {
	    /* Ug.  We don't know shared library extensions.  Hope that
	       systems that use this form don't do shared libraries.  */
1662
	    init_gcc_specs (&obstack,
1663
#ifdef NO_SHARED_LIBGCC_MULTILIB
1664
			    "-lgcc_s"
1665
#else
1666
			    "-lgcc_s%M"
1667
#endif
1668
			    ,
1669 1670
			    "libgcc.a%s",
			    "libgcc_eh.a%s");
1671
	    p += 10;
1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685
	    in_sep = 0;
	  }
	else
	  {
	    obstack_1grow (&obstack, *p);
	    in_sep = (*p == ' ');
	    p += 1;
	  }
      }

    obstack_1grow (&obstack, '\0');
    libgcc_spec = obstack_finish (&obstack);
  }
#endif
1686 1687 1688
#ifdef USE_AS_TRADITIONAL_FORMAT
  /* Prepend "--traditional-format" to whatever asm_spec we had before.  */
  {
1689
    static const char tf[] = "--traditional-format ";
1690 1691 1692 1693 1694
    obstack_grow (&obstack, tf, sizeof(tf) - 1);
    obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
    asm_spec = obstack_finish (&obstack);
  }
#endif
1695 1696 1697 1698 1699 1700
#ifdef LINK_EH_SPEC
  /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
  obstack_grow (&obstack, LINK_EH_SPEC, sizeof(LINK_EH_SPEC) - 1);
  obstack_grow0 (&obstack, link_spec, strlen (link_spec));
  link_spec = obstack_finish (&obstack);
#endif
1701

Michael Meissner committed
1702 1703
  specs = sl;
}
Richard Stallman committed
1704 1705 1706

/* Change the value of spec NAME to SPEC.  If SPEC is empty, then the spec is
   removed; If the spec starts with a + then SPEC is added to the end of the
Mike Stump committed
1707
   current spec.  */
Richard Stallman committed
1708 1709 1710

static void
set_spec (name, spec)
1711 1712
     const char *name;
     const char *spec;
Richard Stallman committed
1713 1714
{
  struct spec_list *sl;
Zack Weinberg committed
1715
  const char *old_spec;
Michael Meissner committed
1716 1717 1718
  int name_len = strlen (name);
  int i;

1719
  /* If this is the first call, initialize the statically allocated specs.  */
1720 1721
  if (!specs)
    {
Kazu Hirata committed
1722
      struct spec_list *next = (struct spec_list *) 0;
1723
      for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
1724 1725 1726 1727 1728 1729 1730 1731
	{
	  sl = &static_specs[i];
	  sl->next = next;
	  next = sl;
	}
      specs = sl;
    }

1732
  /* See if the spec already exists.  */
Richard Stallman committed
1733
  for (sl = specs; sl; sl = sl->next)
Michael Meissner committed
1734
    if (name_len == sl->name_len && !strcmp (sl->name, name))
Richard Stallman committed
1735 1736 1737 1738
      break;

  if (!sl)
    {
1739
      /* Not found - make it.  */
Richard Stallman committed
1740
      sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
1741
      sl->name = xstrdup (name);
Michael Meissner committed
1742 1743 1744 1745
      sl->name_len = name_len;
      sl->ptr_spec = &sl->ptr;
      sl->alloc_p = 0;
      *(sl->ptr_spec) = "";
Richard Stallman committed
1746 1747 1748 1749
      sl->next = specs;
      specs = sl;
    }

Michael Meissner committed
1750
  old_spec = *(sl->ptr_spec);
Kaveh R. Ghazi committed
1751
  *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
1752
		     ? concat (old_spec, spec + 1, NULL)
1753
		     : xstrdup (spec));
Michael Meissner committed
1754

1755 1756
#ifdef DEBUG_SPECS
  if (verbose_flag)
1757
    notice ("Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
1758 1759
#endif

1760
  /* Free the old spec.  */
Michael Meissner committed
1761
  if (old_spec && sl->alloc_p)
Zack Weinberg committed
1762
    free ((PTR) old_spec);
Michael Meissner committed
1763 1764

  sl->alloc_p = 1;
Richard Stallman committed
1765 1766 1767 1768 1769 1770
}

/* Accumulate a command (program name and args), and run it.  */

/* Vector of pointers to arguments in the current line of specifications.  */

Zack Weinberg committed
1771
static const char **argbuf;
Richard Stallman committed
1772 1773 1774 1775 1776 1777 1778 1779 1780

/* Number of elements allocated in argbuf.  */

static int argbuf_length;

/* Number of elements in argbuf currently in use (containing args).  */

static int argbuf_index;

1781 1782 1783
/* 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.  */
Tom Wood committed
1784 1785

static struct temp_name {
1786
  const char *suffix;	/* suffix associated with the code.  */
Tom Wood committed
1787 1788
  int length;		/* strlen (suffix).  */
  int unique;		/* Indicates whether %g or %u/%U was used.  */
1789
  const char *filename;	/* associated filename.  */
Tom Wood committed
1790 1791 1792
  int filename_length;	/* strlen (filename).  */
  struct temp_name *next;
} *temp_names;
1793

Richard Stallman committed
1794 1795 1796 1797
/* Number of commands executed so far.  */

static int execution_count;

1798 1799 1800 1801
/* Number of commands that exited with a signal.  */

static int signal_count;

Richard Stallman committed
1802 1803
/* Name with which this program was invoked.  */

1804
static const char *programname;
Richard Stallman committed
1805

1806 1807 1808 1809 1810 1811 1812 1813 1814
/* Allocate the argument vector.  */

static void
alloc_args ()
{
  argbuf_length = 10;
  argbuf = (const char **) xmalloc (argbuf_length * sizeof (const char *));
}

Richard Stallman committed
1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
/* Clear out the vector of arguments (after a command is executed).  */

static void
clear_args ()
{
  argbuf_index = 0;
}

/* Add one argument to the vector at the end.
   This is done when a space is seen or at the end of the line.
   If DELETE_ALWAYS is nonzero, the arg is a filename
    and the file should be deleted eventually.
   If DELETE_FAILURE is nonzero, the arg is a filename
    and the file should be deleted if this compilation fails.  */

static void
store_arg (arg, delete_always, delete_failure)
Zack Weinberg committed
1832
     const char *arg;
Richard Stallman committed
1833 1834 1835
     int delete_always, delete_failure;
{
  if (argbuf_index + 1 == argbuf_length)
1836
    argbuf
Zack Weinberg committed
1837 1838
      = (const char **) xrealloc (argbuf,
				  (argbuf_length *= 2) * sizeof (const char *));
Richard Stallman committed
1839 1840 1841 1842 1843 1844 1845 1846

  argbuf[argbuf_index++] = arg;
  argbuf[argbuf_index] = 0;

  if (delete_always || delete_failure)
    record_temp_file (arg, delete_always, delete_failure);
}

1847
/* Load specs from a file name named FILENAME, replacing occurrences of
Kazu Hirata committed
1848
   various different types of line-endings, \r\n, \n\r and just \r, with
1849
   a single \n.  */
1850

Kazu Hirata committed
1851
static char *
1852
load_specs (filename)
1853
     const char *filename;
1854 1855 1856 1857 1858
{
  int desc;
  int readlen;
  struct stat statbuf;
  char *buffer;
1859 1860 1861
  char *buffer_p;
  char *specs;
  char *specs_p;
1862 1863

  if (verbose_flag)
1864
    notice ("Reading specs from %s\n", filename);
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880

  /* Open and stat the file.  */
  desc = open (filename, O_RDONLY, 0);
  if (desc < 0)
    pfatal_with_name (filename);
  if (stat (filename, &statbuf) < 0)
    pfatal_with_name (filename);

  /* Read contents of file into BUFFER.  */
  buffer = xmalloc ((unsigned) statbuf.st_size + 1);
  readlen = read (desc, buffer, (unsigned) statbuf.st_size);
  if (readlen < 0)
    pfatal_with_name (filename);
  buffer[readlen] = 0;
  close (desc);

1881 1882 1883 1884 1885 1886 1887
  specs = xmalloc (readlen + 1);
  specs_p = specs;
  for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
    {
      int skip = 0;
      char c = *buffer_p;
      if (c == '\r')
Kazu Hirata committed
1888 1889
	{
	  if (buffer_p > buffer && *(buffer_p - 1) == '\n')	/* \n\r */
1890
	    skip = 1;
Kazu Hirata committed
1891
	  else if (*(buffer_p + 1) == '\n')			/* \r\n */
1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
	    skip = 1;
	  else							/* \r */
	    c = '\n';
	}
      if (! skip)
	*specs_p++ = c;
    }
  *specs_p = '\0';

  free (buffer);
  return (specs);
}

/* Read compilation specs from a file named FILENAME,
   replacing the default ones.

   A suffix which starts with `*' is a definition for
   one of the machine-specific sub-specs.  The "suffix" should be
1910
   *asm, *cc1, *cpp, *link, *startfile, etc.
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921
   The corresponding spec is stored in asm_spec, etc.,
   rather than in the `compilers' vector.

   Anything invalid in the file is a fatal error.  */

static void
read_specs (filename, main_p)
     const char *filename;
     int main_p;
{
  char *buffer;
1922
  char *p;
1923 1924 1925

  buffer = load_specs (filename);

1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944
  /* Scan BUFFER for specs, putting them in the vector.  */
  p = buffer;
  while (1)
    {
      char *suffix;
      char *spec;
      char *in, *out, *p1, *p2, *p3;

      /* Advance P in BUFFER to the next nonblank nocomment line.  */
      p = skip_whitespace (p);
      if (*p == 0)
	break;

      /* Is this a special command that starts with '%'? */
      /* Don't allow this for the main specs file, since it would
	 encourage people to overwrite it.  */
      if (*p == '%' && !main_p)
	{
	  p1 = p;
1945 1946 1947
	  while (*p && *p != '\n')
	    p++;

Kazu Hirata committed
1948 1949
	  /* Skip '\n'.  */
	  p++;
1950

Kazu Hirata committed
1951
	  if (!strncmp (p1, "%include", sizeof ("%include") - 1)
1952 1953
	      && (p1[sizeof "%include" - 1] == ' '
		  || p1[sizeof "%include" - 1] == '\t'))
1954 1955 1956 1957
	    {
	      char *new_filename;

	      p1 += sizeof ("%include");
1958 1959
	      while (*p1 == ' ' || *p1 == '\t')
		p1++;
1960 1961

	      if (*p1++ != '<' || p[-2] != '>')
Kaveh R. Ghazi committed
1962 1963
		fatal ("specs %%include syntax malformed after %ld characters",
		       (long) (p1 - buffer + 1));
1964 1965

	      p[-2] = '\0';
1966
	      new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
1967 1968 1969
	      read_specs (new_filename ? new_filename : p1, FALSE);
	      continue;
	    }
1970 1971 1972
	  else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
		   && (p1[sizeof "%include_noerr" - 1] == ' '
		       || p1[sizeof "%include_noerr" - 1] == '\t'))
1973 1974 1975
	    {
	      char *new_filename;

1976
	      p1 += sizeof "%include_noerr";
Kazu Hirata committed
1977 1978
	      while (*p1 == ' ' || *p1 == '\t')
		p1++;
1979 1980

	      if (*p1++ != '<' || p[-2] != '>')
Kaveh R. Ghazi committed
1981 1982
		fatal ("specs %%include syntax malformed after %ld characters",
		       (long) (p1 - buffer + 1));
1983 1984

	      p[-2] = '\0';
1985
	      new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
1986 1987 1988
	      if (new_filename)
		read_specs (new_filename, FALSE);
	      else if (verbose_flag)
1989
		notice ("could not find specs file %s\n", p1);
1990 1991
	      continue;
	    }
1992 1993 1994
	  else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
		   && (p1[sizeof "%rename" - 1] == ' '
		       || p1[sizeof "%rename" - 1] == '\t'))
1995 1996 1997
	    {
	      int name_len;
	      struct spec_list *sl;
1998
	      struct spec_list *newsl;
1999

2000
	      /* Get original name.  */
2001 2002 2003 2004
	      p1 += sizeof "%rename";
	      while (*p1 == ' ' || *p1 == '\t')
		p1++;

Kazu Hirata committed
2005
	      if (! ISALPHA ((unsigned char) *p1))
Kaveh R. Ghazi committed
2006 2007
		fatal ("specs %%rename syntax malformed after %ld characters",
		       (long) (p1 - buffer));
2008 2009

	      p2 = p1;
Kazu Hirata committed
2010
	      while (*p2 && !ISSPACE ((unsigned char) *p2))
2011 2012
		p2++;

2013
	      if (*p2 != ' ' && *p2 != '\t')
Kaveh R. Ghazi committed
2014 2015
		fatal ("specs %%rename syntax malformed after %ld characters",
		       (long) (p2 - buffer));
2016 2017 2018

	      name_len = p2 - p1;
	      *p2++ = '\0';
2019 2020 2021
	      while (*p2 == ' ' || *p2 == '\t')
		p2++;

Kazu Hirata committed
2022
	      if (! ISALPHA ((unsigned char) *p2))
Kaveh R. Ghazi committed
2023 2024
		fatal ("specs %%rename syntax malformed after %ld characters",
		       (long) (p2 - buffer));
2025

Kazu Hirata committed
2026
	      /* Get new spec name.  */
2027
	      p3 = p2;
Kazu Hirata committed
2028
	      while (*p3 && !ISSPACE ((unsigned char) *p3))
2029 2030
		p3++;

Kazu Hirata committed
2031
	      if (p3 != p - 1)
Kaveh R. Ghazi committed
2032 2033
		fatal ("specs %%rename syntax malformed after %ld characters",
		       (long) (p3 - buffer));
2034 2035 2036 2037 2038 2039 2040 2041 2042
	      *p3 = '\0';

	      for (sl = specs; sl; sl = sl->next)
		if (name_len == sl->name_len && !strcmp (sl->name, p1))
		  break;

	      if (!sl)
		fatal ("specs %s spec was not found to be renamed", p1);

2043
	      if (strcmp (p1, p2) == 0)
2044 2045
		continue;

2046 2047 2048 2049 2050
	      for (newsl = specs; newsl; newsl = newsl->next)
		if (strcmp (newsl->name, p2) == 0)
		  fatal ("%s: attempt to rename spec '%s' to already defined spec '%s'",
		    filename, p1, p2);

2051 2052
	      if (verbose_flag)
		{
2053
		  notice ("rename spec %s to %s\n", p1, p2);
2054
#ifdef DEBUG_SPECS
2055
		  notice ("spec is '%s'\n\n", *(sl->ptr_spec));
2056 2057 2058 2059 2060
#endif
		}

	      set_spec (p2, *(sl->ptr_spec));
	      if (sl->alloc_p)
Zack Weinberg committed
2061
		free ((PTR) *(sl->ptr_spec));
2062 2063 2064 2065 2066 2067

	      *(sl->ptr_spec) = "";
	      sl->alloc_p = 0;
	      continue;
	    }
	  else
Kaveh R. Ghazi committed
2068 2069
	    fatal ("specs unknown %% command after %ld characters",
		   (long) (p1 - buffer));
2070 2071 2072 2073
	}

      /* Find the colon that should end the suffix.  */
      p1 = p;
2074 2075 2076
      while (*p1 && *p1 != ':' && *p1 != '\n')
	p1++;

2077 2078
      /* The colon shouldn't be missing.  */
      if (*p1 != ':')
Kaveh R. Ghazi committed
2079 2080
	fatal ("specs file malformed after %ld characters",
	       (long) (p1 - buffer));
2081

2082 2083
      /* Skip back over trailing whitespace.  */
      p2 = p1;
2084 2085 2086
      while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
	p2--;

2087 2088 2089 2090 2091
      /* Copy the suffix to a string.  */
      suffix = save_string (p, p2 - p);
      /* Find the next line.  */
      p = skip_whitespace (p1 + 1);
      if (p[1] == 0)
Kaveh R. Ghazi committed
2092 2093
	fatal ("specs file malformed after %ld characters",
	       (long) (p - buffer));
2094

2095
      p1 = p;
2096 2097
      /* Find next blank line or end of string.  */
      while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
2098 2099
	p1++;

2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111
      /* Specs end at the blank line and do not include the newline.  */
      spec = save_string (p, p1 - p);
      p = p1;

      /* Delete backslash-newline sequences from the spec.  */
      in = spec;
      out = spec;
      while (*in != 0)
	{
	  if (in[0] == '\\' && in[1] == '\n')
	    in += 2;
	  else if (in[0] == '#')
2112 2113 2114
	    while (*in && *in != '\n')
	      in++;

2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131
	  else
	    *out++ = *in++;
	}
      *out = 0;

      if (suffix[0] == '*')
	{
	  if (! strcmp (suffix, "*link_command"))
	    link_command_spec = spec;
	  else
	    set_spec (suffix + 1, spec);
	}
      else
	{
	  /* Add this pair to the vector.  */
	  compilers
	    = ((struct compiler *)
2132 2133 2134
	       xrealloc (compilers,
			 (n_compilers + 2) * sizeof (struct compiler)));

2135
	  compilers[n_compilers].suffix = suffix;
2136
	  compilers[n_compilers].spec = spec;
2137
	  n_compilers++;
2138
	  memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
2139 2140 2141 2142 2143 2144 2145 2146 2147 2148
	}

      if (*suffix == 0)
	link_command_spec = spec;
    }

  if (link_command_spec == 0)
    fatal ("spec file has no spec for linking");
}

Richard Stallman committed
2149 2150 2151 2152 2153
/* Record the names of temporary files we tell compilers to write,
   and delete them at the end of the run.  */

/* This is the common prefix we use to make temp file names.
   It is chosen once for each run of this program.
2154
   It is substituted into a spec by %g or %j.
Richard Stallman committed
2155 2156 2157 2158 2159
   Thus, all temp file names contain this prefix.
   In practice, all temp file names start with this prefix.

   This prefix comes from the envvar TMPDIR if it is defined;
   otherwise, from the P_tmpdir macro if that is defined;
2160 2161
   otherwise, in /usr/tmp or /tmp;
   or finally the current directory if all else fails.  */
Richard Stallman committed
2162

2163
static const char *temp_filename;
Richard Stallman committed
2164 2165 2166 2167 2168 2169 2170 2171 2172

/* Length of the prefix.  */

static int temp_filename_length;

/* Define the list of temporary files to delete.  */

struct temp_file
{
2173
  const char *name;
Richard Stallman committed
2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187
  struct temp_file *next;
};

/* Queue of files to delete on success or failure of compilation.  */
static struct temp_file *always_delete_queue;
/* Queue of files to delete on failure of compilation.  */
static struct temp_file *failure_delete_queue;

/* Record FILENAME as a file to be deleted automatically.
   ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
   otherwise delete it in any case.
   FAIL_DELETE nonzero means delete it if a compilation step fails;
   otherwise delete it in any case.  */

2188
void
Richard Stallman committed
2189
record_temp_file (filename, always_delete, fail_delete)
2190
     const char *filename;
Richard Stallman committed
2191 2192 2193
     int always_delete;
     int fail_delete;
{
2194
  char *const name = xstrdup (filename);
Richard Stallman committed
2195 2196 2197

  if (always_delete)
    {
2198
      struct temp_file *temp;
Richard Stallman committed
2199 2200 2201
      for (temp = always_delete_queue; temp; temp = temp->next)
	if (! strcmp (name, temp->name))
	  goto already1;
2202

Richard Stallman committed
2203 2204 2205 2206
      temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
      temp->next = always_delete_queue;
      temp->name = name;
      always_delete_queue = temp;
2207

Richard Stallman committed
2208 2209 2210 2211 2212
    already1:;
    }

  if (fail_delete)
    {
2213
      struct temp_file *temp;
Richard Stallman committed
2214 2215 2216
      for (temp = failure_delete_queue; temp; temp = temp->next)
	if (! strcmp (name, temp->name))
	  goto already2;
2217

Richard Stallman committed
2218 2219 2220 2221
      temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
      temp->next = failure_delete_queue;
      temp->name = name;
      failure_delete_queue = temp;
2222

Richard Stallman committed
2223 2224 2225 2226 2227 2228 2229
    already2:;
    }
}

/* Delete all the temporary files whose names we previously recorded.  */

static void
2230
delete_if_ordinary (name)
2231
     const char *name;
2232 2233 2234 2235 2236 2237 2238 2239 2240
{
  struct stat st;
#ifdef DEBUG
  int i, c;

  printf ("Delete %s? (y or n) ", name);
  fflush (stdout);
  i = getchar ();
  if (i != '\n')
2241 2242 2243
    while ((c = getchar ()) != '\n' && c != EOF)
      ;

2244 2245
  if (i == 'y' || i == 'Y')
#endif /* DEBUG */
2246
    if (stat (name, &st) >= 0 && S_ISREG (st.st_mode))
2247 2248 2249 2250 2251 2252
      if (unlink (name) < 0)
	if (verbose_flag)
	  perror_with_name (name);
}

static void
Richard Stallman committed
2253 2254
delete_temp_files ()
{
2255
  struct temp_file *temp;
Richard Stallman committed
2256 2257

  for (temp = always_delete_queue; temp; temp = temp->next)
2258
    delete_if_ordinary (temp->name);
Richard Stallman committed
2259 2260 2261 2262 2263 2264 2265 2266
  always_delete_queue = 0;
}

/* Delete all the files to be deleted on error.  */

static void
delete_failure_queue ()
{
2267
  struct temp_file *temp;
Richard Stallman committed
2268 2269

  for (temp = failure_delete_queue; temp; temp = temp->next)
2270
    delete_if_ordinary (temp->name);
Richard Stallman committed
2271 2272 2273 2274 2275 2276 2277 2278
}

static void
clear_failure_queue ()
{
  failure_delete_queue = 0;
}

2279 2280
/* Build a list of search directories from PATHS.
   PREFIX is a string to prepend to the list.
2281
   If CHECK_DIR_P is nonzero we ensure the directory exists.
2282 2283
   This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
   It is also used by the --print-search-dirs flag.  */
2284

2285 2286
static char *
build_search_list (paths, prefix, check_dir_p)
2287
     struct path_prefix *paths;
2288
     const char *prefix;
2289
     int check_dir_p;
2290 2291
{
  int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
2292 2293
  int just_suffix_len
    = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
2294 2295 2296
  int first_time = TRUE;
  struct prefix_list *pprefix;

2297
  obstack_grow (&collect_obstack, prefix, strlen (prefix));
2298
  obstack_1grow (&collect_obstack, '=');
2299 2300 2301 2302 2303

  for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
    {
      int len = strlen (pprefix->prefix);

2304
      if (machine_suffix
2305
	  && (! check_dir_p
2306
	      || is_directory (pprefix->prefix, machine_suffix, 0)))
2307 2308
	{
	  if (!first_time)
2309
	    obstack_1grow (&collect_obstack, PATH_SEPARATOR);
Kazu Hirata committed
2310

2311 2312 2313 2314 2315
	  first_time = FALSE;
	  obstack_grow (&collect_obstack, pprefix->prefix, len);
	  obstack_grow (&collect_obstack, machine_suffix, suffix_len);
	}

2316 2317
      if (just_machine_suffix
	  && pprefix->require_machine_suffix == 2
2318
	  && (! check_dir_p
2319
	      || is_directory (pprefix->prefix, just_machine_suffix, 0)))
Charles Hannum committed
2320
	{
2321
	  if (! first_time)
2322
	    obstack_1grow (&collect_obstack, PATH_SEPARATOR);
Kazu Hirata committed
2323

Charles Hannum committed
2324 2325
	  first_time = FALSE;
	  obstack_grow (&collect_obstack, pprefix->prefix, len);
2326 2327
	  obstack_grow (&collect_obstack, just_machine_suffix,
			just_suffix_len);
Charles Hannum committed
2328 2329
	}

2330
      if (! pprefix->require_machine_suffix)
2331
	{
2332
	  if (! first_time)
2333
	    obstack_1grow (&collect_obstack, PATH_SEPARATOR);
2334 2335 2336 2337 2338

	  first_time = FALSE;
	  obstack_grow (&collect_obstack, pprefix->prefix, len);
	}
    }
2339

2340
  obstack_1grow (&collect_obstack, '\0');
2341
  return obstack_finish (&collect_obstack);
2342 2343
}

Mike Stump committed
2344 2345
/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
   for collect.  */
2346 2347 2348 2349

static void
putenv_from_prefixes (paths, env_var)
     struct path_prefix *paths;
2350
     const char *env_var;
2351 2352 2353
{
  putenv (build_search_list (paths, env_var, 1));
}
2354

2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374
/* Check whether NAME can be accessed in MODE.  This is like access,
   except that it never considers directories to be executable.  */

static int
access_check (name, mode)
     const char *name;
     int mode;
{
  if (mode == X_OK)
    {
      struct stat st;

      if (stat (name, &st) < 0
	  || S_ISDIR (st.st_mode))
	return -1;
    }

  return access (name, mode);
}

Richard Stallman committed
2375 2376
/* Search for NAME using the prefix list PREFIXES.  MODE is passed to
   access to check permissions.
Mike Stump committed
2377
   Return 0 if not found, otherwise return its name, allocated with malloc.  */
Richard Stallman committed
2378 2379

static char *
2380
find_a_file (pprefix, name, mode, multilib)
Richard Stallman committed
2381
     struct path_prefix *pprefix;
2382
     const char *name;
2383
     int mode, multilib;
Richard Stallman committed
2384 2385
{
  char *temp;
2386 2387
  const char *const file_suffix =
    ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
Richard Stallman committed
2388 2389
  struct prefix_list *pl;
  int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
2390
  const char *multilib_name, *multilib_os_name;
Richard Stallman committed
2391

2392
#ifdef DEFAULT_ASSEMBLER
2393
  if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
2394
    return xstrdup (DEFAULT_ASSEMBLER);
2395 2396 2397
#endif

#ifdef DEFAULT_LINKER
2398 2399
  if (! strcmp(name, "ld") && access (DEFAULT_LINKER, mode) == 0)
    return xstrdup (DEFAULT_LINKER);
2400 2401
#endif

Richard Stallman committed
2402 2403 2404
  if (machine_suffix)
    len += strlen (machine_suffix);

2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420
  multilib_name = name;
  multilib_os_name = name;
  if (multilib && multilib_os_dir)
    {
      int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0;
      int len2 = strlen (multilib_os_dir) + 1;

      len += len1 > len2 ? len1 : len2;
      if (multilib_dir)
	multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name,
				  NULL));
      if (strcmp (multilib_os_dir, ".") != 0)
	multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name,
				    NULL));
    }

Richard Stallman committed
2421 2422 2423 2424
  temp = xmalloc (len);

  /* Determine the filename to execute (special case for absolute paths).  */

2425
  if (IS_ABSOLUTE_PATHNAME (name))
Richard Stallman committed
2426
    {
2427
      if (access (name, mode) == 0)
Richard Stallman committed
2428 2429 2430 2431 2432 2433 2434 2435
	{
	  strcpy (temp, name);
	  return temp;
	}
    }
  else
    for (pl = pprefix->plist; pl; pl = pl->next)
      {
2436 2437 2438
	const char *this_name
	  = pl->os_multilib ? multilib_os_name : multilib_name;

Richard Stallman committed
2439 2440 2441
	if (machine_suffix)
	  {
	    /* Some systems have a suffix for executable files.
2442
	       So try appending that first.  */
Richard Stallman committed
2443 2444
	    if (file_suffix[0] != 0)
	      {
2445 2446
		strcpy (temp, pl->prefix);
		strcat (temp, machine_suffix);
2447
		strcat (temp, multilib_name);
Richard Stallman committed
2448
		strcat (temp, file_suffix);
2449
		if (access_check (temp, mode) == 0)
Richard Stallman committed
2450 2451 2452 2453 2454 2455
		  {
		    if (pl->used_flag_ptr != 0)
		      *pl->used_flag_ptr = 1;
		    return temp;
		  }
	      }
2456

2457
	    /* Now try just the multilib_name.  */
Charles Hannum committed
2458
	    strcpy (temp, pl->prefix);
2459
	    strcat (temp, machine_suffix);
2460
	    strcat (temp, multilib_name);
2461
	    if (access_check (temp, mode) == 0)
Charles Hannum committed
2462 2463 2464 2465 2466
	      {
		if (pl->used_flag_ptr != 0)
		  *pl->used_flag_ptr = 1;
		return temp;
	      }
2467 2468 2469 2470 2471 2472
	  }

	/* Certain prefixes are tried with just the machine type,
	   not the version.  This is used for finding as, ld, etc.  */
	if (just_machine_suffix && pl->require_machine_suffix == 2)
	  {
Charles Hannum committed
2473
	    /* Some systems have a suffix for executable files.
2474
	       So try appending that first.  */
Charles Hannum committed
2475 2476
	    if (file_suffix[0] != 0)
	      {
2477 2478
		strcpy (temp, pl->prefix);
		strcat (temp, just_machine_suffix);
2479
		strcat (temp, multilib_name);
Charles Hannum committed
2480
		strcat (temp, file_suffix);
2481
		if (access_check (temp, mode) == 0)
Charles Hannum committed
2482 2483 2484 2485 2486 2487
		  {
		    if (pl->used_flag_ptr != 0)
		      *pl->used_flag_ptr = 1;
		    return temp;
		  }
	      }
2488

Richard Stallman committed
2489
	    strcpy (temp, pl->prefix);
2490
	    strcat (temp, just_machine_suffix);
2491
	    strcat (temp, multilib_name);
2492
	    if (access_check (temp, mode) == 0)
Richard Stallman committed
2493 2494 2495 2496 2497
	      {
		if (pl->used_flag_ptr != 0)
		  *pl->used_flag_ptr = 1;
		return temp;
	      }
2498 2499 2500 2501
	  }

	/* Certain prefixes can't be used without the machine suffix
	   when the machine or version is explicitly specified.  */
2502
	if (! pl->require_machine_suffix)
2503
	  {
Richard Stallman committed
2504
	    /* Some systems have a suffix for executable files.
2505
	       So try appending that first.  */
Richard Stallman committed
2506 2507
	    if (file_suffix[0] != 0)
	      {
2508
		strcpy (temp, pl->prefix);
2509
		strcat (temp, this_name);
Richard Stallman committed
2510
		strcat (temp, file_suffix);
2511
		if (access_check (temp, mode) == 0)
Richard Stallman committed
2512 2513 2514 2515 2516 2517
		  {
		    if (pl->used_flag_ptr != 0)
		      *pl->used_flag_ptr = 1;
		    return temp;
		  }
	      }
2518 2519

	    strcpy (temp, pl->prefix);
2520
	    strcat (temp, this_name);
2521
	    if (access_check (temp, mode) == 0)
2522 2523 2524 2525 2526
	      {
		if (pl->used_flag_ptr != 0)
		  *pl->used_flag_ptr = 1;
		return temp;
	      }
Richard Stallman committed
2527 2528 2529 2530 2531 2532 2533
	  }
      }

  free (temp);
  return 0;
}

2534
/* Ranking of prefixes in the sort list. -B prefixes are put before
Kazu Hirata committed
2535
   all others.  */
2536 2537 2538 2539 2540 2541 2542

enum path_prefix_priority
{
  PREFIX_PRIORITY_B_OPT,
  PREFIX_PRIORITY_LAST
};

2543
/* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
2544 2545
   order according to PRIORITY.  Within each PRIORITY, new entries are
   appended.
Richard Stallman committed
2546 2547 2548

   If WARN is nonzero, we will warn if no file is found
   through this prefix.  WARN should point to an int
Charles Hannum committed
2549 2550
   which will be set to 1 if this entry is used.

2551 2552
   COMPONENT is the value to be passed to update_path.

Charles Hannum committed
2553 2554 2555
   REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
   the complete value of machine_suffix.
   2 means try both machine_suffix and just_machine_suffix.  */
Richard Stallman committed
2556 2557

static void
2558 2559
add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
	    warn, os_multilib)
Richard Stallman committed
2560
     struct path_prefix *pprefix;
2561 2562
     const char *prefix;
     const char *component;
2563
     /* enum prefix_priority */ int priority;
Richard Stallman committed
2564 2565
     int require_machine_suffix;
     int *warn;
2566
     int os_multilib;
Richard Stallman committed
2567 2568 2569 2570
{
  struct prefix_list *pl, **prev;
  int len;

2571 2572 2573 2574
  for (prev = &pprefix->plist;
       (*prev) != NULL && (*prev)->priority <= priority;
       prev = &(*prev)->next)
    ;
Richard Stallman committed
2575 2576 2577

  /* Keep track of the longest prefix */

2578
  prefix = update_path (prefix, component);
Richard Stallman committed
2579 2580 2581 2582 2583
  len = strlen (prefix);
  if (len > pprefix->max_len)
    pprefix->max_len = len;

  pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
2584
  pl->prefix = prefix;
Richard Stallman committed
2585 2586
  pl->require_machine_suffix = require_machine_suffix;
  pl->used_flag_ptr = warn;
2587
  pl->priority = priority;
2588
  pl->os_multilib = os_multilib;
Richard Stallman committed
2589 2590 2591
  if (warn)
    *warn = 0;

2592 2593 2594
  /* Insert after PREV */
  pl->next = (*prev);
  (*prev) = pl;
Richard Stallman committed
2595
}
2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622

/* 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;
{
  if (!IS_ABSOLUTE_PATHNAME (prefix))
    abort ();

  if (target_system_root)
    {
      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);
}
Richard Stallman committed
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636

/* Execute the command specified by the arguments on the current line of spec.
   When using pipes, this includes several piped-together commands
   with `|' between them.

   Return 0 if successful, -1 if failed.  */

static int
execute ()
{
  int i;
  int n_commands;		/* # of command.  */
  char *string;
  struct command
Kazu Hirata committed
2637 2638 2639 2640 2641
  {
    const char *prog;		/* program name.  */
    const char **argv;		/* vector of args.  */
    int pid;			/* pid of process for this command.  */
  };
Richard Stallman committed
2642 2643 2644

  struct command *commands;	/* each command buffer with above info.  */

2645 2646 2647
  if (processing_spec_function)
    abort ();

Richard Stallman committed
2648 2649 2650 2651 2652 2653
  /* Count # of piped commands.  */
  for (n_commands = 1, i = 0; i < argbuf_index; i++)
    if (strcmp (argbuf[i], "|") == 0)
      n_commands++;

  /* Get storage for each command.  */
Kazu Hirata committed
2654
  commands = (struct command *) alloca (n_commands * sizeof (struct command));
Richard Stallman committed
2655 2656 2657 2658 2659 2660 2661

  /* Split argbuf into its separate piped processes,
     and record info about each one.
     Also search for the programs that are to be run.  */

  commands[0].prog = argbuf[0]; /* first command.  */
  commands[0].argv = &argbuf[0];
2662
  string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0);
Bob Manson committed
2663

Richard Stallman committed
2664 2665 2666 2667 2668 2669
  if (string)
    commands[0].argv[0] = string;

  for (n_commands = 1, i = 0; i < argbuf_index; i++)
    if (strcmp (argbuf[i], "|") == 0)
      {				/* each command.  */
2670
#if defined (__MSDOS__) || defined (OS2) || defined (VMS)
Kazu Hirata committed
2671
	fatal ("-pipe not supported");
Richard Stallman committed
2672 2673 2674 2675
#endif
	argbuf[i] = 0;	/* termination of command args.  */
	commands[n_commands].prog = argbuf[i + 1];
	commands[n_commands].argv = &argbuf[i + 1];
2676 2677
	string = find_a_file (&exec_prefixes, commands[n_commands].prog,
			      X_OK, 0);
Richard Stallman committed
2678 2679 2680 2681 2682 2683 2684 2685 2686
	if (string)
	  commands[n_commands].argv[0] = string;
	n_commands++;
      }

  argbuf[argbuf_index] = 0;

  /* If -v, print what we are about to do, and maybe query.  */

2687
  if (verbose_flag)
Richard Stallman committed
2688
    {
Nick Clifton committed
2689 2690 2691
      /* For help listings, put a blank line between sub-processes.  */
      if (print_help_list)
	fputc ('\n', stderr);
Kazu Hirata committed
2692

Richard Stallman committed
2693
      /* Print each piped command as a separate line.  */
Kazu Hirata committed
2694
      for (i = 0; i < n_commands; i++)
Richard Stallman committed
2695
	{
2696
	  const char *const *j;
Richard Stallman committed
2697

2698 2699
	  if (verbose_only_flag)
	    {
2700 2701
	      for (j = commands[i].argv; *j; j++)
		{
2702
		  const char *p;
2703 2704 2705 2706 2707 2708 2709 2710 2711
		  fprintf (stderr, " \"");
		  for (p = *j; *p; ++p)
		    {
		      if (*p == '"' || *p == '\\' || *p == '$')
			fputc ('\\', stderr);
		      fputc (*p, stderr);
		    }
		  fputc ('"', stderr);
		}
2712 2713
	    }
	  else
2714 2715
	    for (j = commands[i].argv; *j; j++)
	      fprintf (stderr, " %s", *j);
Richard Stallman committed
2716 2717 2718 2719 2720 2721 2722

	  /* Print a pipe symbol after all but the last command.  */
	  if (i + 1 != n_commands)
	    fprintf (stderr, " |");
	  fprintf (stderr, "\n");
	}
      fflush (stderr);
2723
      if (verbose_only_flag != 0)
2724
	return 0;
Richard Stallman committed
2725
#ifdef DEBUG
2726
      notice ("\nGo ahead? (y or n) ");
Richard Stallman committed
2727 2728 2729
      fflush (stderr);
      i = getchar ();
      if (i != '\n')
2730 2731 2732
	while (getchar () != '\n')
	  ;

Richard Stallman committed
2733 2734 2735 2736 2737
      if (i != 'y' && i != 'Y')
	return 0;
#endif /* DEBUG */
    }

2738
#ifdef ENABLE_VALGRIND_CHECKING
2739
  /* Run the each command through valgrind.  To simplify prepending the
2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764
     path to valgrind and the option "-q" (for quiet operation unless
     something triggers), we allocate a separate argv array.  */

  for (i = 0; i < n_commands; i++)
    {
      const char **argv;
      int argc;
      int j;

      for (argc = 0; commands[i].argv[argc] != NULL; argc++)
	;

      argv = alloca ((argc + 3) * sizeof (char *));

      argv[0] = VALGRIND_PATH;
      argv[1] = "-q";
      for (j = 2; j < argc + 2; j++)
	argv[j] = commands[i].argv[j - 2];
      argv[j] = NULL;

      commands[i].argv = argv;
      commands[i].prog = argv[0];
    }
#endif

Richard Stallman committed
2765 2766 2767 2768
  /* Run each piped subprocess.  */

  for (i = 0; i < n_commands; i++)
    {
2769
      char *errmsg_fmt, *errmsg_arg;
Zack Weinberg committed
2770
      const char *string = commands[i].argv[0];
Richard Stallman committed
2771

2772 2773 2774
      /* For some bizarre reason, the second argument of execvp() is
	 char *const *, not const char *const *.  */
      commands[i].pid = pexecute (string, (char *const *) commands[i].argv,
2775 2776 2777 2778 2779
				  programname, temp_filename,
				  &errmsg_fmt, &errmsg_arg,
				  ((i == 0 ? PEXECUTE_FIRST : 0)
				   | (i + 1 == n_commands ? PEXECUTE_LAST : 0)
				   | (string == commands[i].prog
2780 2781
				      ? PEXECUTE_SEARCH : 0)
				   | (verbose_flag ? PEXECUTE_VERBOSE : 0)));
2782 2783 2784

      if (commands[i].pid == -1)
	pfatal_pexecute (errmsg_fmt, errmsg_arg);
Richard Stallman committed
2785 2786

      if (string != commands[i].prog)
Zack Weinberg committed
2787
	free ((PTR) string);
Richard Stallman committed
2788 2789 2790 2791 2792 2793
    }

  execution_count++;

  /* Wait for all the subprocesses to finish.
     We don't care what order they finish in;
2794 2795 2796
     we know that N_COMMANDS waits will get them all.
     Ignore subprocesses that we don't know about,
     since they can be spawned by the process that exec'ed us.  */
Richard Stallman committed
2797 2798 2799

  {
    int ret_code = 0;
2800 2801
#ifdef HAVE_GETRUSAGE
    struct timeval d;
2802
    double ut = 0.0, st = 0.0;
2803
#endif
Richard Stallman committed
2804

Kazu Hirata committed
2805
    for (i = 0; i < n_commands;)
Richard Stallman committed
2806
      {
2807
	int j;
Richard Stallman committed
2808 2809 2810
	int status;
	int pid;

2811
	pid = pwait (commands[i].pid, &status, 0);
Richard Stallman committed
2812 2813 2814
	if (pid < 0)
	  abort ();

2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825
#ifdef HAVE_GETRUSAGE
	if (report_times)
	  {
	    /* getrusage returns the total resource usage of all children
	       up to now.  Copy the previous values into prus, get the
	       current statistics, then take the difference.  */

	    prus = rus;
	    getrusage (RUSAGE_CHILDREN, &rus);
	    d.tv_sec = rus.ru_utime.tv_sec - prus.ru_utime.tv_sec;
	    d.tv_usec = rus.ru_utime.tv_usec - prus.ru_utime.tv_usec;
Kazu Hirata committed
2826
	    ut = (double) d.tv_sec + (double) d.tv_usec / 1.0e6;
Kazu Hirata committed
2827

2828 2829
	    d.tv_sec = rus.ru_stime.tv_sec - prus.ru_stime.tv_sec;
	    d.tv_usec = rus.ru_stime.tv_usec - prus.ru_stime.tv_usec;
Kazu Hirata committed
2830
	    st = (double) d.tv_sec + (double) d.tv_usec / 1.0e6;
2831 2832 2833
	  }
#endif

2834 2835 2836 2837
	for (j = 0; j < n_commands; j++)
	  if (commands[j].pid == pid)
	    {
	      i++;
2838
	      if (WIFSIGNALED (status))
2839
		{
2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856
#ifdef SIGPIPE
		  /* SIGPIPE is a special case.  It happens in -pipe mode
		     when the compiler dies before the preprocessor is
		     done, or the assembler dies before the compiler is
		     done.  There's generally been an error already, and
		     this is just fallout.  So don't generate another error
		     unless we would otherwise have succeeded.  */
		  if (WTERMSIG (status) == SIGPIPE
		      && (signal_count || greatest_status >= MIN_FATAL_STATUS))
		    ;
		  else
#endif
		    fatal ("\
Internal error: %s (program %s)\n\
Please submit a full bug report.\n\
See %s for instructions.",
			   strsignal (WTERMSIG (status)), commands[j].prog,
2857
			   bug_report_url);
2858 2859 2860 2861 2862 2863 2864 2865 2866
		  signal_count++;
		  ret_code = -1;
		}
	      else if (WIFEXITED (status)
		       && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
		{
		  if (WEXITSTATUS (status) > greatest_status)
		    greatest_status = WEXITSTATUS (status);
		  ret_code = -1;
2867
		}
2868 2869 2870 2871
#ifdef HAVE_GETRUSAGE
	      if (report_times && ut + st != 0)
		notice ("# %s %.2f %.2f\n", commands[j].prog, ut, st);
#endif
2872 2873
	      break;
	    }
Richard Stallman committed
2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884
      }
    return ret_code;
  }
}

/* Find all the switches given to us
   and make a vector describing them.
   The elements of the vector are strings, one per switch given.
   If a switch uses following arguments, then the `part1' field
   is the switch itself and the `args' field
   is a null-terminated vector containing the following arguments.
2885 2886 2887 2888
   The `live_cond' field is:
   0 when initialized
   1 if the switch is true in a conditional spec,
   -1 if false (overridden by a later switch)
2889
   -2 if this switch should be ignored (used in %<S)
2890
   The `validated' field is nonzero if any spec has looked at this switch;
Richard Stallman committed
2891 2892
   if it remains zero at the end of the run, it must be meaningless.  */

2893 2894 2895 2896 2897
#define SWITCH_OK       0
#define SWITCH_FALSE   -1
#define SWITCH_IGNORE  -2
#define SWITCH_LIVE     1

Richard Stallman committed
2898 2899
struct switchstr
{
2900
  const char *part1;
Zack Weinberg committed
2901
  const char **args;
2902
  int live_cond;
2903 2904
  unsigned char validated;
  unsigned char ordering;
Richard Stallman committed
2905 2906 2907 2908 2909 2910 2911 2912
};

static struct switchstr *switches;

static int n_switches;

struct infile
{
2913 2914
  const char *name;
  const char *language;
Richard Stallman committed
2915 2916 2917 2918 2919 2920
};

/* Also a vector of input files specified.  */

static struct infile *infiles;

2921
int n_infiles;
Richard Stallman committed
2922

2923
/* This counts the number of libraries added by lang_specific_driver, so that
2924 2925 2926 2927
   we can tell if there were any user supplied any files or libraries.  */

static int added_libraries;

Richard Stallman committed
2928 2929
/* And a vector of corresponding output files is made up later.  */

2930
const char **outfiles;
Richard Stallman committed
2931

2932 2933 2934 2935
/* 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.  */
2936
static int *warn_std_ptr = 0;
2937

2938
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
2939 2940

/* Convert NAME to a new name if it is the standard suffix.  DO_EXE
2941 2942
   is true if we should look for an executable suffix.  DO_OBJ
   is true if we should look for an object suffix.  */
2943

2944
static const char *
2945
convert_filename (name, do_exe, do_obj)
2946 2947
     const char *name;
     int do_exe ATTRIBUTE_UNUSED;
2948
     int do_obj ATTRIBUTE_UNUSED;
2949
{
2950
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
2951
  int i;
2952
#endif
2953 2954 2955 2956
  int len;

  if (name == NULL)
    return NULL;
Kazu Hirata committed
2957

2958
  len = strlen (name);
2959

2960 2961
#ifdef HAVE_TARGET_OBJECT_SUFFIX
  /* Convert x.o to x.obj if TARGET_OBJECT_SUFFIX is ".obj".  */
2962
  if (do_obj && len > 2
2963 2964 2965
      && name[len - 2] == '.'
      && name[len - 1] == 'o')
    {
2966
      obstack_grow (&obstack, name, len - 2);
2967
      obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
2968 2969 2970 2971
      name = obstack_finish (&obstack);
    }
#endif

2972
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
2973 2974
  /* If there is no filetype, make it the executable suffix (which includes
     the ".").  But don't get confused if we have just "-o".  */
2975
  if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || (len == 2 && name[0] == '-'))
2976 2977
    return name;

2978
  for (i = len - 1; i >= 0; i--)
2979
    if (IS_DIR_SEPARATOR (name[i]))
2980 2981 2982
      break;

  for (i++; i < len; i++)
2983 2984 2985 2986
    if (name[i] == '.')
      return name;

  obstack_grow (&obstack, name, len);
Richard Kenner committed
2987 2988
  obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
		 strlen (TARGET_EXECUTABLE_SUFFIX));
2989 2990 2991 2992 2993 2994 2995
  name = obstack_finish (&obstack);
#endif

  return name;
}
#endif

Nick Clifton committed
2996 2997 2998 2999
/* Display the command line switches accepted by gcc.  */
static void
display_help ()
{
3000 3001
  printf (_("Usage: %s [options] file...\n"), programname);
  fputs (_("Options:\n"), stdout);
Nick Clifton committed
3002

3003 3004
  fputs (_("  -pass-exit-codes         Exit with highest error code from a phase\n"), stdout);
  fputs (_("  --help                   Display this information\n"), stdout);
3005
  fputs (_("  --target-help            Display target specific command line options\n"), stdout);
Nick Clifton committed
3006
  if (! verbose_flag)
3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018
    fputs (_("  (Use '-v --help' to display command line options of sub-processes)\n"), stdout);
  fputs (_("  -dumpspecs               Display all of the built in spec strings\n"), stdout);
  fputs (_("  -dumpversion             Display the version of the compiler\n"), stdout);
  fputs (_("  -dumpmachine             Display the compiler's target processor\n"), stdout);
  fputs (_("  -print-search-dirs       Display the directories in the compiler's search path\n"), stdout);
  fputs (_("  -print-libgcc-file-name  Display the name of the compiler's companion library\n"), stdout);
  fputs (_("  -print-file-name=<lib>   Display the full path to library <lib>\n"), stdout);
  fputs (_("  -print-prog-name=<prog>  Display the full path to compiler component <prog>\n"), stdout);
  fputs (_("  -print-multi-directory   Display the root directory for versions of libgcc\n"), stdout);
  fputs (_("\
  -print-multi-lib         Display the mapping between command line options and\n\
                           multiple library search directories\n"), stdout);
3019
  fputs (_("  -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
3020 3021 3022
  fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler\n"), stdout);
  fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor\n"), stdout);
  fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker\n"), stdout);
3023 3024
  fputs (_("  -Xassembler <arg>        Pass <arg> on to the assembler\n"), stdout);
  fputs (_("  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor\n"), stdout);
3025 3026 3027 3028
  fputs (_("  -Xlinker <arg>           Pass <arg> on to the linker\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);
3029
  fputs (_("  -specs=<file>            Override built-in specs with the contents of <file>\n"), stdout);
3030 3031 3032 3033 3034
  fputs (_("  -std=<standard>          Assume that the input sources are for <standard>\n"), stdout);
  fputs (_("  -B <directory>           Add <directory> to the compiler's search paths\n"), stdout);
  fputs (_("  -b <machine>             Run gcc for target <machine>, if installed\n"), stdout);
  fputs (_("  -V <version>             Run gcc version number <version>, if installed\n"), stdout);
  fputs (_("  -v                       Display the programs invoked by the compiler\n"), stdout);
3035
  fputs (_("  -###                     Like -v but options quoted and commands not executed\n"), stdout);
3036 3037 3038 3039 3040 3041 3042
  fputs (_("  -E                       Preprocess only; do not compile, assemble or link\n"), stdout);
  fputs (_("  -S                       Compile only; do not assemble or link\n"), stdout);
  fputs (_("  -c                       Compile and assemble, but do not link\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\
3043
                           'none' means revert to the default behavior of\n\
3044 3045 3046
                           guessing the language based on the file's extension\n\
"), stdout);

3047
  printf (_("\
3048 3049 3050
\nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
 passed on to the various sub-processes invoked by %s.  In order to pass\n\
 other options on to these processes the -W<letter> options must be used.\n\
3051
"), programname);
Nick Clifton committed
3052 3053 3054 3055 3056

  /* The rest of the options are displayed by invocations of the various
     sub-processes.  */
}

Kazu Hirata committed
3057 3058
static void
add_preprocessor_option (option, len)
Kazu Hirata committed
3059
     const char *option;
3060
     int len;
Kazu Hirata committed
3061
{
3062
  n_preprocessor_options++;
Kazu Hirata committed
3063

3064 3065 3066 3067 3068 3069 3070
  if (! preprocessor_options)
    preprocessor_options
      = (char **) xmalloc (n_preprocessor_options * sizeof (char *));
  else
    preprocessor_options
      = (char **) xrealloc (preprocessor_options,
			    n_preprocessor_options * sizeof (char *));
Kazu Hirata committed
3071

3072 3073
  preprocessor_options [n_preprocessor_options - 1] =
    save_string (option, len);
Nick Clifton committed
3074
}
Kazu Hirata committed
3075 3076 3077

static void
add_assembler_option (option, len)
Kazu Hirata committed
3078
     const char *option;
3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091
     int len;
{
  n_assembler_options++;

  if (! assembler_options)
    assembler_options
      = (char **) xmalloc (n_assembler_options * sizeof (char *));
  else
    assembler_options
      = (char **) xrealloc (assembler_options,
			    n_assembler_options * sizeof (char *));

  assembler_options [n_assembler_options - 1] = save_string (option, len);
Nick Clifton committed
3092
}
Kazu Hirata committed
3093 3094 3095

static void
add_linker_option (option, len)
Kazu Hirata committed
3096 3097
     const char *option;
     int len;
3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109
{
  n_linker_options++;

  if (! linker_options)
    linker_options
      = (char **) xmalloc (n_linker_options * sizeof (char *));
  else
    linker_options
      = (char **) xrealloc (linker_options,
			    n_linker_options * sizeof (char *));

  linker_options [n_linker_options - 1] = save_string (option, len);
Nick Clifton committed
3110
}
Nick Clifton committed
3111

Richard Stallman committed
3112 3113 3114 3115 3116 3117
/* Create the vector `switches' and its contents.
   Store its length in `n_switches'.  */

static void
process_command (argc, argv)
     int argc;
3118
     const char *const *argv;
Richard Stallman committed
3119
{
3120
  int i;
3121 3122
  const char *temp;
  char *temp1;
Zack Weinberg committed
3123
  const char *spec_lang = 0;
Richard Stallman committed
3124
  int last_language_n_infiles;
3125 3126
  int have_c = 0;
  int have_o = 0;
3127
  int lang_n_infiles = 0;
3128 3129
#ifdef MODIFY_TARGET_NAME
  int is_modify_target_name;
3130
  int j;
3131
#endif
Richard Stallman committed
3132

3133
  GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
3134

Richard Stallman committed
3135 3136
  n_switches = 0;
  n_infiles = 0;
3137
  added_libraries = 0;
3138

3139 3140
  /* Figure compiler version from version string.  */

Kazu Hirata committed
3141
  compiler_version = temp1 = xstrdup (version_string);
3142

3143
  for (; *temp1; ++temp1)
3144
    {
3145
      if (*temp1 == ' ')
3146
	{
3147
	  *temp1 = '\0';
3148 3149 3150
	  break;
	}
    }
Richard Stallman committed
3151

3152 3153 3154 3155 3156 3157 3158
  /* If there is a -V or -b option (or both), process it now, before
     trying to interpret the rest of the command line.  */
  if (argc > 1 && argv[1][0] == '-'
      && (argv[1][1] == 'V' || argv[1][1] == 'b'))
    {
      const char *new_version = DEFAULT_TARGET_VERSION;
      const char *new_machine = DEFAULT_TARGET_MACHINE;
3159 3160
      const char *progname = argv[0];
      char **new_argv;
3161 3162 3163
      char *new_argv0;
      int baselen;
      
3164 3165
      while (argc > 1 && argv[1][0] == '-'
	     && (argv[1][1] == 'V' || argv[1][1] == 'b'))
3166
	{
3167
	  char opt = argv[1][1];
3168
	  const char *arg;
3169
	  if (argv[1][2] != '\0')
3170
	    {
3171
	      arg = argv[1] + 2;
3172
	      argc -= 1;
3173
	      argv += 1;
3174 3175 3176
	    }
	  else if (argc > 2)
	    {
3177
	      arg = argv[2];
3178
	      argc -= 2;
3179
	      argv += 2;
3180 3181 3182 3183 3184 3185 3186 3187 3188
	    }
	  else
	    fatal ("`-%c' option must have argument", opt);
	  if (opt == 'V')
	    new_version = arg;
	  else
	    new_machine = arg;
	}

3189 3190
      for (baselen = strlen (progname); baselen > 0; baselen--)
	if (IS_DIR_SEPARATOR (progname[baselen-1]))
3191
	  break;
3192
      new_argv0 = xmemdup (progname, baselen, 
3193 3194 3195 3196 3197 3198
			   baselen + concat_length (new_version, new_machine,
						    "-gcc-", NULL) + 1);
      strcpy (new_argv0 + baselen, new_machine);
      strcat (new_argv0, "-gcc-");
      strcat (new_argv0, new_version);

3199 3200
      new_argv = xmemdup (argv, (argc + 1) * sizeof (argv[0]),
			  (argc + 1) * sizeof (argv[0]));
3201 3202 3203
      new_argv[0] = new_argv0;

      execvp (new_argv0, new_argv);
3204
      fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
3205 3206
    }

Tom Tromey committed
3207 3208 3209 3210 3211 3212 3213 3214 3215 3216
  /* 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].  */

#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);
      if (gcc_exec_prefix)
3217
	putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
Tom Tromey committed
3218 3219
    }
#endif
Richard Stallman committed
3220

3221
  if (gcc_exec_prefix)
Richard Stallman committed
3222
    {
3223
      int len = strlen (gcc_exec_prefix);
3224

Kazu Hirata committed
3225
      if (len > (int) sizeof ("/lib/gcc-lib/") - 1
3226
	  && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
3227 3228
	{
	  temp = gcc_exec_prefix + len - sizeof ("/lib/gcc-lib/") + 1;
3229
	  if (IS_DIR_SEPARATOR (*temp)
Kazu Hirata committed
3230
	      && strncmp (temp + 1, "lib", 3) == 0
3231
	      && IS_DIR_SEPARATOR (temp[4])
Kazu Hirata committed
3232
	      && strncmp (temp + 5, "gcc-lib", 7) == 0)
3233 3234 3235 3236
	    len -= sizeof ("/lib/gcc-lib/") - 1;
	}

      set_std_prefix (gcc_exec_prefix, len);
3237
      add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC",
3238
		  PREFIX_PRIORITY_LAST, 0, NULL, 0);
3239
      add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
3240
		  PREFIX_PRIORITY_LAST, 0, NULL, 0);
Richard Stallman committed
3241 3242 3243 3244 3245
    }

  /* COMPILER_PATH and LIBRARY_PATH have values
     that are lists of directory names with colons.  */

3246
  GET_ENVIRONMENT (temp, "COMPILER_PATH");
Richard Stallman committed
3247 3248
  if (temp)
    {
3249
      const char *startp, *endp;
Richard Stallman committed
3250 3251 3252 3253 3254
      char *nstore = (char *) alloca (strlen (temp) + 3);

      startp = endp = temp;
      while (1)
	{
3255
	  if (*endp == PATH_SEPARATOR || *endp == 0)
Richard Stallman committed
3256
	    {
Kazu Hirata committed
3257
	      strncpy (nstore, startp, endp - startp);
Richard Stallman committed
3258
	      if (endp == startp)
3259
		strcpy (nstore, concat (".", dir_separator_str, NULL));
3260
	      else if (!IS_DIR_SEPARATOR (endp[-1]))
Richard Stallman committed
3261
		{
Kazu Hirata committed
3262 3263
		  nstore[endp - startp] = DIR_SEPARATOR;
		  nstore[endp - startp + 1] = 0;
Richard Stallman committed
3264 3265
		}
	      else
Kazu Hirata committed
3266
		nstore[endp - startp] = 0;
3267
	      add_prefix (&exec_prefixes, nstore, 0,
3268
			  PREFIX_PRIORITY_LAST, 0, NULL, 0);
3269
	      add_prefix (&include_prefixes,
3270
			  concat (nstore, "include", NULL),
3271
			  0, PREFIX_PRIORITY_LAST, 0, NULL, 0);
Richard Stallman committed
3272 3273 3274 3275 3276 3277 3278 3279 3280
	      if (*endp == 0)
		break;
	      endp = startp = endp + 1;
	    }
	  else
	    endp++;
	}
    }

3281
  GET_ENVIRONMENT (temp, LIBRARY_PATH_ENV);
Michael Meissner committed
3282
  if (temp && *cross_compile == '0')
Richard Stallman committed
3283
    {
3284
      const char *startp, *endp;
Richard Stallman committed
3285 3286 3287 3288 3289
      char *nstore = (char *) alloca (strlen (temp) + 3);

      startp = endp = temp;
      while (1)
	{
3290
	  if (*endp == PATH_SEPARATOR || *endp == 0)
Richard Stallman committed
3291
	    {
Kazu Hirata committed
3292
	      strncpy (nstore, startp, endp - startp);
Richard Stallman committed
3293
	      if (endp == startp)
3294
		strcpy (nstore, concat (".", dir_separator_str, NULL));
3295
	      else if (!IS_DIR_SEPARATOR (endp[-1]))
Richard Stallman committed
3296
		{
Kazu Hirata committed
3297 3298
		  nstore[endp - startp] = DIR_SEPARATOR;
		  nstore[endp - startp + 1] = 0;
Richard Stallman committed
3299 3300
		}
	      else
Kazu Hirata committed
3301
		nstore[endp - startp] = 0;
3302
	      add_prefix (&startfile_prefixes, nstore, NULL,
3303
			  PREFIX_PRIORITY_LAST, 0, NULL, 1);
Richard Stallman committed
3304 3305 3306 3307 3308 3309 3310 3311 3312 3313
	      if (*endp == 0)
		break;
	      endp = startp = endp + 1;
	    }
	  else
	    endp++;
	}
    }

  /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
3314
  GET_ENVIRONMENT (temp, "LPATH");
Michael Meissner committed
3315
  if (temp && *cross_compile == '0')
Richard Stallman committed
3316
    {
3317
      const char *startp, *endp;
Richard Stallman committed
3318 3319 3320 3321 3322
      char *nstore = (char *) alloca (strlen (temp) + 3);

      startp = endp = temp;
      while (1)
	{
3323
	  if (*endp == PATH_SEPARATOR || *endp == 0)
Richard Stallman committed
3324
	    {
Kazu Hirata committed
3325
	      strncpy (nstore, startp, endp - startp);
Richard Stallman committed
3326
	      if (endp == startp)
3327
		strcpy (nstore, concat (".", dir_separator_str, NULL));
3328
	      else if (!IS_DIR_SEPARATOR (endp[-1]))
Richard Stallman committed
3329
		{
Kazu Hirata committed
3330 3331
		  nstore[endp - startp] = DIR_SEPARATOR;
		  nstore[endp - startp + 1] = 0;
Richard Stallman committed
3332 3333
		}
	      else
Kazu Hirata committed
3334
		nstore[endp - startp] = 0;
3335
	      add_prefix (&startfile_prefixes, nstore, NULL,
3336
			  PREFIX_PRIORITY_LAST, 0, NULL, 1);
Richard Stallman committed
3337 3338 3339 3340 3341 3342 3343 3344 3345
	      if (*endp == 0)
		break;
	      endp = startp = endp + 1;
	    }
	  else
	    endp++;
	}
    }

3346 3347 3348
  /* Convert new-style -- options to old-style.  */
  translate_options (&argc, &argv);

3349
  /* Do language-specific adjustment/addition of flags.  */
3350
  lang_specific_driver (&argc, &argv, &added_libraries);
3351

Richard Stallman committed
3352 3353 3354 3355 3356 3357 3358 3359
  /* 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.
     Here we also parse the switches that cc itself uses (e.g. -v).  */

  for (i = 1; i < argc; i++)
    {
      if (! strcmp (argv[i], "-dumpspecs"))
	{
Michael Meissner committed
3360
	  struct spec_list *sl;
3361
	  init_spec ();
Michael Meissner committed
3362 3363
	  for (sl = specs; sl; sl = sl->next)
	    printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
Kazu Hirata committed
3364 3365
	  if (link_command_spec)
	    printf ("*link_command:\n%s\n\n", link_command_spec);
Richard Stallman committed
3366 3367 3368 3369
	  exit (0);
	}
      else if (! strcmp (argv[i], "-dumpversion"))
	{
3370
	  printf ("%s\n", spec_version);
Richard Stallman committed
3371 3372
	  exit (0);
	}
3373 3374 3375
      else if (! strcmp (argv[i], "-dumpmachine"))
	{
	  printf ("%s\n", spec_machine);
Kazu Hirata committed
3376
	  exit (0);
3377
	}
3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388
      else if (strcmp (argv[i], "-fversion") == 0)
	{
	  /* 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);
	  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);
	  exit (0);
	}
Nick Clifton committed
3389 3390 3391 3392 3393 3394 3395 3396
      else if (strcmp (argv[i], "-fhelp") == 0)
	{
	  /* translate_options () has turned --help into -fhelp.  */
	  print_help_list = 1;

	  /* We will be passing a dummy file on to the sub-processes.  */
	  n_infiles++;
	  n_switches++;
Kazu Hirata committed
3397

3398 3399 3400
	  /* CPP driver cannot obtain switch from cc1_options.  */
	  if (is_cpp_driver)
	    add_preprocessor_option ("--help", 6);
Nick Clifton committed
3401 3402 3403
	  add_assembler_option ("--help", 6);
	  add_linker_option ("--help", 6);
	}
3404
      else if (strcmp (argv[i], "-ftarget-help") == 0)
3405 3406 3407
	{
	  /* translate_options() has turned --target-help into -ftarget-help.  */
	  target_help_flag = 1;
3408

3409 3410 3411
	  /* We will be passing a dummy file on to the sub-processes.  */
	  n_infiles++;
	  n_switches++;
3412

3413 3414 3415
	  /* CPP driver cannot obtain switch from cc1_options.  */
	  if (is_cpp_driver)
	    add_preprocessor_option ("--target-help", 13);
3416 3417 3418
	  add_assembler_option ("--target-help", 13);
	  add_linker_option ("--target-help", 13);
	}
Richard Kenner committed
3419 3420 3421 3422 3423
      else if (! strcmp (argv[i], "-pass-exit-codes"))
	{
	  pass_exit_codes = 1;
	  n_switches++;
	}
3424 3425
      else if (! strcmp (argv[i], "-print-search-dirs"))
	print_search_dirs = 1;
3426
      else if (! strcmp (argv[i], "-print-libgcc-file-name"))
3427
	print_file_name = "libgcc.a";
3428
      else if (! strncmp (argv[i], "-print-file-name=", 17))
3429
	print_file_name = argv[i] + 17;
3430
      else if (! strncmp (argv[i], "-print-prog-name=", 17))
3431
	print_prog_name = argv[i] + 17;
Doug Evans committed
3432 3433 3434 3435
      else if (! strcmp (argv[i], "-print-multi-lib"))
	print_multi_lib = 1;
      else if (! strcmp (argv[i], "-print-multi-directory"))
	print_multi_directory = 1;
3436 3437
      else if (! strcmp (argv[i], "-print-multi-os-directory"))
	print_multi_os_directory = 1;
3438 3439 3440 3441 3442 3443 3444 3445 3446 3447
      else if (! strncmp (argv[i], "-Wa,", 4))
	{
	  int prev, j;
	  /* Pass the rest of this option to the assembler.  */

	  /* Split the argument at commas.  */
	  prev = 4;
	  for (j = 4; argv[i][j]; j++)
	    if (argv[i][j] == ',')
	      {
Nick Clifton committed
3448
		add_assembler_option (argv[i] + prev, j - prev);
3449 3450
		prev = j + 1;
	      }
Kazu Hirata committed
3451

3452
	  /* Record the part after the last comma.  */
Nick Clifton committed
3453
	  add_assembler_option (argv[i] + prev, j - prev);
3454
	}
3455 3456 3457 3458 3459 3460 3461 3462 3463 3464
      else if (! strncmp (argv[i], "-Wp,", 4))
	{
	  int prev, j;
	  /* Pass the rest of this option to the preprocessor.  */

	  /* Split the argument at commas.  */
	  prev = 4;
	  for (j = 4; argv[i][j]; j++)
	    if (argv[i][j] == ',')
	      {
Nick Clifton committed
3465
		add_preprocessor_option (argv[i] + prev, j - prev);
3466 3467
		prev = j + 1;
	      }
Kazu Hirata committed
3468

3469
	  /* Record the part after the last comma.  */
Nick Clifton committed
3470
	  add_preprocessor_option (argv[i] + prev, j - prev);
3471
	}
3472
      else if (argv[i][0] == '+' && argv[i][1] == 'e')
3473
	/* The +e options to the C++ front-end.  */
3474
	n_switches++;
3475
      else if (strncmp (argv[i], "-Wl,", 4) == 0)
3476 3477 3478 3479 3480 3481
	{
	  int j;
	  /* Split the argument at commas.  */
	  for (j = 3; argv[i][j]; j++)
	    n_infiles += (argv[i][j] == ',');
	}
3482 3483 3484 3485 3486 3487 3488 3489
      else if (strcmp (argv[i], "-Xlinker") == 0)
	{
	  if (i + 1 == argc)
	    fatal ("argument to `-Xlinker' is missing");

	  n_infiles++;
	  i++;
	}
3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503
      else if (strcmp (argv[i], "-Xpreprocessor") == 0)
	{
	  if (i + 1 == argc)
	    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");

	  add_assembler_option (argv[i+1], strlen (argv[i+1]));
	}
3504 3505 3506 3507 3508 3509 3510 3511
      else if (strcmp (argv[i], "-l") == 0)
	{
	  if (i + 1 == argc)
	    fatal ("argument to `-l' is missing");

	  n_infiles++;
	  i++;
	}
3512 3513
      else if (strncmp (argv[i], "-l", 2) == 0)
	n_infiles++;
3514 3515 3516 3517 3518
      else if (strcmp (argv[i], "-save-temps") == 0)
	{
	  save_temps_flag = 1;
	  n_switches++;
	}
Michael Meissner committed
3519 3520 3521 3522 3523 3524 3525
      else if (strcmp (argv[i], "-specs") == 0)
	{
	  struct user_specs *user = (struct user_specs *)
	    xmalloc (sizeof (struct user_specs));
	  if (++i >= argc)
	    fatal ("argument to `-specs' is missing");

Kazu Hirata committed
3526
	  user->next = (struct user_specs *) 0;
Michael Meissner committed
3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540
	  user->filename = argv[i];
	  if (user_specs_tail)
	    user_specs_tail->next = user;
	  else
	    user_specs_head = user;
	  user_specs_tail = user;
	}
      else if (strncmp (argv[i], "-specs=", 7) == 0)
	{
	  struct user_specs *user = (struct user_specs *)
	    xmalloc (sizeof (struct user_specs));
	  if (strlen (argv[i]) == 7)
	    fatal ("argument to `-specs=' is missing");

Kazu Hirata committed
3541
	  user->next = (struct user_specs *) 0;
Kazu Hirata committed
3542
	  user->filename = argv[i] + 7;
Michael Meissner committed
3543 3544 3545 3546 3547 3548
	  if (user_specs_tail)
	    user_specs_tail->next = user;
	  else
	    user_specs_head = user;
	  user_specs_tail = user;
	}
3549 3550
      else if (strcmp (argv[i], "-time") == 0)
	report_times = 1;
3551 3552 3553 3554 3555 3556 3557
      else if (strcmp (argv[i], "-pipe") == 0)
	{
	  /* -pipe has to go into the switches array as well as
	     setting a flag.  */
	  use_pipes = 1;
	  n_switches++;
	}
3558 3559 3560 3561 3562 3563 3564 3565 3566
      else if (strcmp (argv[i], "-###") == 0)
	{
	  /* This is similar to -v except that there is no execution
	     of the commands and the echoed arguments are quoted.  It
	     is intended for use in shell scripts to capture the
	     driver-generated command line.  */
	  verbose_only_flag++;
	  verbose_flag++;
	}
3567
      else if (argv[i][0] == '-' && argv[i][1] != 0)
Richard Stallman committed
3568
	{
3569 3570
	  const char *p = &argv[i][1];
	  int c = *p;
Richard Stallman committed
3571 3572 3573 3574

	  switch (c)
	    {
	    case 'b':
3575 3576
	    case 'V':
	      fatal ("`-%c' must come at the start of the command line", c);
Richard Stallman committed
3577 3578 3579 3580
	      break;

	    case 'B':
	      {
Zack Weinberg committed
3581
		const char *value;
3582 3583
		int len;

Richard Stallman committed
3584 3585 3586 3587 3588 3589
		if (p[1] == 0 && i + 1 == argc)
		  fatal ("argument to `-B' is missing");
		if (p[1] == 0)
		  value = argv[++i];
		else
		  value = p + 1;
3590 3591 3592 3593

		len = strlen (value);

		/* Catch the case where the user has forgotten to append a
3594
		   directory separator to the path.  Note, they may be using
3595 3596 3597 3598 3599 3600 3601 3602
		   -B to add an executable name prefix, eg "i386-elf-", in
		   order to distinguish between multiple installations of
		   GCC in the same directory.  Hence we must check to see
		   if appending a directory separator actually makes a
		   valid directory name.  */
		if (! IS_DIR_SEPARATOR (value [len - 1])
		    && is_directory (value, "", 0))
		  {
3603 3604 3605 3606 3607
		    char *tmp = xmalloc (len + 2);
		    strcpy (tmp, value);
		    tmp[len] = DIR_SEPARATOR;
		    tmp[++ len] = 0;
		    value = tmp;
3608
		  }
3609

3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620
		/* As a kludge, if the arg is "[foo/]stageN/", just
		   add "[foo/]include" to the include prefix.  */
		if ((len == 7
		     || (len > 7
			 && (IS_DIR_SEPARATOR (value[len - 8]))))
		    && strncmp (value + len - 7, "stage", 5) == 0
		    && ISDIGIT (value[len - 2])
		    && (IS_DIR_SEPARATOR (value[len - 1])))
		  {
		    if (len == 7)
		      add_prefix (&include_prefixes, "include", NULL,
3621
				  PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
3622 3623 3624 3625 3626 3627 3628
		    else
		      {
			char * string = xmalloc (len + 1);

			strncpy (string, value, len - 7);
			strcpy (string + len - 7, "include");
			add_prefix (&include_prefixes, string, NULL,
3629
				    PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
3630 3631 3632
		      }
		  }

3633
		add_prefix (&exec_prefixes, value, NULL,
3634
			    PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
3635
		add_prefix (&startfile_prefixes, value, NULL,
3636
			    PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
3637
		add_prefix (&include_prefixes, concat (value, "include", NULL),
3638
			    NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
Kazu Hirata committed
3639
		n_switches++;
Richard Stallman committed
3640 3641 3642 3643 3644
	      }
	      break;

	    case 'v':	/* Print our subcommands and print versions.  */
	      n_switches++;
3645 3646 3647 3648 3649
	      /* If they do anything other than exactly `-v', don't set
		 verbose_flag; rather, continue on to give the error.  */
	      if (p[1] != 0)
		break;
	      verbose_flag++;
Richard Stallman committed
3650 3651
	      break;

3652
	    case 'S':
3653 3654
	    case 'c':
	      if (p[1] == 0)
Richard Stallman committed
3655
		{
3656
		  have_c = 1;
3657
		  n_switches++;
Richard Stallman committed
3658 3659
		  break;
		}
3660
	      goto normal_switch;
3661 3662 3663

	    case 'o':
	      have_o = 1;
3664
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
3665 3666 3667
	      if (! have_c)
		{
		  int skip;
Kazu Hirata committed
3668

3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683
		  /* Forward scan, just in case -S or -c is specified
		     after -o.  */
		  int j = i + 1;
		  if (p[1] == 0)
		    ++j;
		  while (j < argc)
		    {
		      if (argv[j][0] == '-')
			{
			  if (SWITCH_CURTAILS_COMPILATION (argv[j][1])
			      && argv[j][2] == 0)
			    {
			      have_c = 1;
			      break;
			    }
3684
			  else if ((skip = SWITCH_TAKES_ARG (argv[j][1])))
3685
			    j += skip - (argv[j][2] != 0);
3686
			  else if ((skip = WORD_SWITCH_TAKES_ARG (argv[j] + 1)))
3687 3688 3689 3690 3691 3692
			    j += skip;
			}
		      j++;
		    }
		}
#endif
3693
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
3694
	      if (p[1] == 0)
3695
		argv[i + 1] = convert_filename (argv[i + 1], ! have_c, 0);
3696
	      else
3697
		argv[i] = convert_filename (argv[i], ! have_c, 0);
3698
#endif
3699
	      goto normal_switch;
3700

Richard Stallman committed
3701
	    default:
3702
	    normal_switch:
3703 3704 3705 3706

#ifdef MODIFY_TARGET_NAME
	      is_modify_target_name = 0;

3707
	      for (j = 0; j < ARRAY_SIZE (modify_target); j++)
3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739
		if (! strcmp (argv[i], modify_target[j].sw))
		  {
		    char *new_name
		      = (char *) xmalloc (strlen (modify_target[j].str)
					  + strlen (spec_machine));
		    const char *p, *r;
		    char *q;
		    int made_addition = 0;

		    is_modify_target_name = 1;
		    for (p = spec_machine, q = new_name; *p != 0; )
		      {
			if (modify_target[j].add_del == DELETE
			    && (! strncmp (q, modify_target[j].str,
					   strlen (modify_target[j].str))))
			  p += strlen (modify_target[j].str);
			else if (modify_target[j].add_del == ADD
				 && ! made_addition && *p == '-')
			  {
			    for (r = modify_target[j].str; *r != 0; )
			      *q++ = *r++;
			    made_addition = 1;
			  }

			*q++ = *p++;
		      }

		    spec_machine = new_name;
		  }

	      if (is_modify_target_name)
		break;
3740
#endif
3741

Richard Stallman committed
3742 3743 3744 3745 3746 3747 3748 3749 3750
	      n_switches++;

	      if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
		i += SWITCH_TAKES_ARG (c) - (p[1] != 0);
	      else if (WORD_SWITCH_TAKES_ARG (p))
		i += WORD_SWITCH_TAKES_ARG (p);
	    }
	}
      else
3751 3752 3753 3754
	{
	  n_infiles++;
	  lang_n_infiles++;
	}
Richard Stallman committed
3755 3756
    }

3757
  if (have_c && have_o && lang_n_infiles > 1)
3758
    fatal ("cannot specify -o with -c or -S and multiple compilations");
3759

3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772
  if ((save_temps_flag || report_times) && use_pipes)
    {
      /* -save-temps overrides -pipe, so that temp files are produced */
      if (save_temps_flag)
	error ("warning: -pipe ignored because -save-temps specified");
      /* -time overrides -pipe because we can't get correct stats when
	 multiple children are running at once.  */
      else if (report_times)
	error ("warning: -pipe ignored because -time specified");

      use_pipes = 0;
    }
  
Richard Stallman committed
3773 3774 3775 3776
  /* 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
     (such as cpp) rather than those of the host system.  */
Charles Hannum committed
3777 3778
  /* Use 2 as fourth arg meaning try just the machine as a suffix,
     as well as trying the machine and the version.  */
3779
#ifndef OS2
Richard Kenner committed
3780
  add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
3781
	      PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
3782
  add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
3783
	      PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
3784
  add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
3785
	      PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
3786
#endif
Richard Stallman committed
3787

3788
  add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
3789
	      PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
3790
  add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS",
3791
	      PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
Richard Stallman committed
3792

Kazu Hirata committed
3793
  tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
3794
			   dir_separator_str, NULL);
3795

3796
  /* If tooldir is relative, base it on exec_prefixes.  A relative
3797 3798 3799 3800 3801 3802
     tooldir lets us move the installed tree as a unit.

     If GCC_EXEC_PREFIX is defined, then we want to add two relative
     directories, so that we can search both the user specified directory
     and the standard place.  */

3803
  if (!IS_ABSOLUTE_PATHNAME (tooldir_prefix))
3804 3805 3806 3807
    {
      if (gcc_exec_prefix)
	{
	  char *gcc_exec_tooldir_prefix
3808
	    = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
3809
		      spec_version, dir_separator_str, tooldir_prefix, NULL);
3810

3811
	  add_prefix (&exec_prefixes,
Kazu Hirata committed
3812
		      concat (gcc_exec_tooldir_prefix, "bin",
3813
			      dir_separator_str, NULL),
3814
		      NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0);
3815
	  add_prefix (&startfile_prefixes,
Kazu Hirata committed
3816
		      concat (gcc_exec_tooldir_prefix, "lib",
3817
			      dir_separator_str, NULL),
3818
		      NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
3819 3820
	}

3821
      tooldir_prefix = concat (standard_exec_prefix, spec_machine,
Kazu Hirata committed
3822
			       dir_separator_str, spec_version,
3823
			       dir_separator_str, tooldir_prefix, NULL);
3824 3825
    }

Kazu Hirata committed
3826
  add_prefix (&exec_prefixes,
3827
	      concat (tooldir_prefix, "bin", dir_separator_str, NULL),
3828
	      "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0);
3829
  add_prefix (&startfile_prefixes,
3830
	      concat (tooldir_prefix, "lib", dir_separator_str, NULL),
3831
	      "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
3832

3833 3834 3835 3836 3837 3838 3839 3840 3841
  if (target_system_root && gcc_exec_prefix)
    {
      char *tmp_prefix = make_relative_prefix (argv[0],
					       standard_bindir_prefix,
					       target_system_root);
      if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
	target_system_root = tmp_prefix;
    }

3842 3843
  /* More prefixes are enabled in main, after we read the specs file
     and determine whether this is cross-compilation or not.  */
Richard Stallman committed
3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859

  /* 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));
  n_switches = 0;
  n_infiles = 0;
  last_language_n_infiles = -1;

  /* This, time, copy the text of each switch and store a pointer
     to the copy in the vector of switches.
     Store all the infiles in their vector.  */

  for (i = 1; i < argc; i++)
    {
3860
      /* Just skip the switches that were handled by the preceding loop.  */
3861 3862 3863
#ifdef MODIFY_TARGET_NAME
      is_modify_target_name = 0;

3864
      for (j = 0; j < ARRAY_SIZE (modify_target); j++)
3865 3866 3867 3868 3869 3870 3871
	if (! strcmp (argv[i], modify_target[j].sw))
	  is_modify_target_name = 1;

      if (is_modify_target_name)
	;
      else
#endif
3872
      if (! strncmp (argv[i], "-Wa,", 4))
3873
	;
3874 3875
      else if (! strncmp (argv[i], "-Wp,", 4))
	;
Richard Kenner committed
3876 3877
      else if (! strcmp (argv[i], "-pass-exit-codes"))
	;
3878 3879
      else if (! strcmp (argv[i], "-print-search-dirs"))
	;
3880
      else if (! strcmp (argv[i], "-print-libgcc-file-name"))
3881
	;
3882 3883 3884 3885
      else if (! strncmp (argv[i], "-print-file-name=", 17))
	;
      else if (! strncmp (argv[i], "-print-prog-name=", 17))
	;
Doug Evans committed
3886 3887 3888 3889
      else if (! strcmp (argv[i], "-print-multi-lib"))
	;
      else if (! strcmp (argv[i], "-print-multi-directory"))
	;
3890 3891
      else if (! strcmp (argv[i], "-print-multi-os-directory"))
	;
3892 3893 3894 3895
      else if (! strcmp (argv[i], "-ftarget-help"))
	;
      else if (! strcmp (argv[i], "-fhelp"))
	;
3896 3897 3898
      else if (argv[i][0] == '+' && argv[i][1] == 'e')
	{
	  /* Compensate for the +e options to the C++ front-end;
3899
	     they're there simply for cfront call-compatibility.  We do
3900 3901 3902 3903 3904
	     some magic in default_compilers to pass them down properly.
	     Note we deliberately start at the `+' here, to avoid passing
	     -e0 or -e1 down into the linker.  */
	  switches[n_switches].part1 = &argv[i][0];
	  switches[n_switches].args = 0;
3905
	  switches[n_switches].live_cond = SWITCH_OK;
3906
	  switches[n_switches].validated = 0;
3907 3908
	  n_switches++;
	}
3909 3910
      else if (strncmp (argv[i], "-Wl,", 4) == 0)
	{
3911 3912 3913 3914 3915 3916
	  int prev, j;
	  /* Split the argument at commas.  */
	  prev = 4;
	  for (j = 4; argv[i][j]; j++)
	    if (argv[i][j] == ',')
	      {
3917
		infiles[n_infiles].language = "*";
3918 3919 3920 3921 3922
		infiles[n_infiles++].name
		  = save_string (argv[i] + prev, j - prev);
		prev = j + 1;
	      }
	  /* Record the part after the last comma.  */
3923
	  infiles[n_infiles].language = "*";
3924
	  infiles[n_infiles++].name = argv[i] + prev;
3925 3926 3927
	}
      else if (strcmp (argv[i], "-Xlinker") == 0)
	{
3928
	  infiles[n_infiles].language = "*";
3929 3930
	  infiles[n_infiles++].name = argv[++i];
	}
3931 3932 3933 3934 3935 3936 3937 3938 3939 3940
      else if (strcmp (argv[i], "-Xassembler") == 0)
	{
	  infiles[n_infiles].language = "*";
	  infiles[n_infiles++].name = argv[++i];
	}
      else if (strcmp (argv[i], "-Xpreprocessor") == 0)
	{
	  infiles[n_infiles].language = "*";
	  infiles[n_infiles++].name = argv[++i];
	}
3941 3942 3943 3944
      else if (strcmp (argv[i], "-l") == 0)
	{ /* POSIX allows separation of -l and the lib arg;
	     canonicalize by concatenating -l with its arg */
	  infiles[n_infiles].language = "*";
3945
	  infiles[n_infiles++].name = concat ("-l", argv[++i], NULL);
3946
	}
3947 3948
      else if (strncmp (argv[i], "-l", 2) == 0)
	{
3949
	  infiles[n_infiles].language = "*";
3950 3951
	  infiles[n_infiles++].name = argv[i];
	}
Michael Meissner committed
3952 3953 3954 3955
      else if (strcmp (argv[i], "-specs") == 0)
	i++;
      else if (strncmp (argv[i], "-specs=", 7) == 0)
	;
3956 3957
      else if (strcmp (argv[i], "-time") == 0)
	;
3958 3959
      else if (strcmp (argv[i], "-###") == 0)
	;
3960
      else if (argv[i][0] == '-' && argv[i][1] != 0)
Richard Stallman committed
3961
	{
Zack Weinberg committed
3962 3963
	  const char *p = &argv[i][1];
	  int c = *p;
Richard Stallman committed
3964 3965 3966 3967 3968 3969 3970 3971 3972 3973

	  if (c == 'x')
	    {
	      if (p[1] == 0 && i + 1 == argc)
		fatal ("argument to `-x' is missing");
	      if (p[1] == 0)
		spec_lang = argv[++i];
	      else
		spec_lang = p + 1;
	      if (! strcmp (spec_lang, "none"))
3974 3975 3976
		/* Suppress the warning if -xnone comes after the last input
		   file, because alternate command interfaces like g++ might
		   find it useful to place -xnone after each input file.  */
Richard Stallman committed
3977 3978 3979 3980 3981 3982 3983 3984
		spec_lang = 0;
	      else
		last_language_n_infiles = n_infiles;
	      continue;
	    }
	  switches[n_switches].part1 = p;
	  /* Deal with option arguments in separate argv elements.  */
	  if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
3985 3986 3987 3988
	      || WORD_SWITCH_TAKES_ARG (p))
	    {
	      int j = 0;
	      int n_args = WORD_SWITCH_TAKES_ARG (p);
Richard Stallman committed
3989

3990 3991 3992 3993 3994 3995 3996 3997
	      if (n_args == 0)
		{
		  /* Count only the option arguments in separate argv elements.  */
		  n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
		}
	      if (i + n_args >= argc)
		fatal ("argument to `-%s' is missing", p);
	      switches[n_switches].args
Zack Weinberg committed
3998
		= (const char **) xmalloc ((n_args + 1) * sizeof(const char *));
3999 4000 4001 4002
	      while (j < n_args)
		switches[n_switches].args[j++] = argv[++i];
	      /* Null-terminate the vector.  */
	      switches[n_switches].args[j] = 0;
Richard Stallman committed
4003
	    }
4004
	  else if (strchr (switches_need_spaces, c))
4005
	    {
4006 4007 4008 4009 4010
	      /* On some systems, ld cannot handle some options without
		 a space.  So split the option from its argument.  */
	      char *part1 = (char *) xmalloc (2);
	      part1[0] = c;
	      part1[1] = '\0';
Kazu Hirata committed
4011

4012
	      switches[n_switches].part1 = part1;
Zack Weinberg committed
4013 4014
	      switches[n_switches].args
		= (const char **) xmalloc (2 * sizeof (const char *));
4015
	      switches[n_switches].args[0] = xstrdup (p+1);
4016 4017 4018
	      switches[n_switches].args[1] = 0;
	    }
	  else
Richard Stallman committed
4019
	    switches[n_switches].args = 0;
4020

4021
	  switches[n_switches].live_cond = SWITCH_OK;
4022
	  switches[n_switches].validated = 0;
4023
	  switches[n_switches].ordering = 0;
4024
	  /* These are always valid, since gcc.c itself understands them.  */
4025 4026
	  if (!strcmp (p, "save-temps")
	      || !strcmp (p, "static-libgcc")
4027 4028
	      || !strcmp (p, "shared-libgcc")
	      || !strcmp (p, "pipe"))
4029
	    switches[n_switches].validated = 1;
Kazu Hirata committed
4030 4031 4032
	  else
	    {
	      char ch = switches[n_switches].part1[0];
4033
	      if (ch == 'B')
Kazu Hirata committed
4034 4035
		switches[n_switches].validated = 1;
	    }
Richard Stallman committed
4036 4037 4038 4039
	  n_switches++;
	}
      else
	{
4040
#ifdef HAVE_TARGET_OBJECT_SUFFIX
4041
	  argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
4042 4043
#endif

4044
	  if (strcmp (argv[i], "-") != 0 && access (argv[i], F_OK) < 0)
4045 4046 4047 4048 4049 4050 4051 4052 4053
	    {
	      perror_with_name (argv[i]);
	      error_count++;
	    }
	  else
	    {
	      infiles[n_infiles].language = spec_lang;
	      infiles[n_infiles++].name = argv[i];
	    }
Richard Stallman committed
4054 4055 4056
	}
    }

4057
  if (n_infiles == last_language_n_infiles && spec_lang != 0)
4058
    error ("warning: `-x %s' after last input file has no effect", spec_lang);
Richard Stallman committed
4059

4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090
  /* Ensure we only invoke each subprocess once.  */
  if (target_help_flag || print_help_list)
    {
      n_infiles = 1;

      /* Create a dummy input file, so that we can pass --target-help on to
	 the various sub-processes.  */
      infiles[0].language = "c";
      infiles[0].name   = "help-dummy";

      if (target_help_flag)
	{
	  switches[n_switches].part1     = "--target-help";
	  switches[n_switches].args      = 0;
	  switches[n_switches].live_cond = SWITCH_OK;
	  switches[n_switches].validated = 0;

	  n_switches++;
	}

      if (print_help_list)
	{
	  switches[n_switches].part1     = "--help";
	  switches[n_switches].args      = 0;
	  switches[n_switches].live_cond = SWITCH_OK;
	  switches[n_switches].validated = 0;

	  n_switches++;
	}
    }

Richard Stallman committed
4091 4092 4093
  switches[n_switches].part1 = 0;
  infiles[n_infiles].name = 0;
}
4094

4095
/* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150
   and place that in the environment.  */

static void
set_collect_gcc_options ()
{
  int i;
  int first_time;

  /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
     the compiler.  */
  obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
		sizeof ("COLLECT_GCC_OPTIONS=") - 1);

  first_time = TRUE;
  for (i = 0; (int) i < n_switches; i++)
    {
      const char *const *args;
      const char *p, *q;
      if (!first_time)
	obstack_grow (&collect_obstack, " ", 1);

      first_time = FALSE;

      /* Ignore elided switches.  */
      if (switches[i].live_cond == SWITCH_IGNORE)
	continue;

      obstack_grow (&collect_obstack, "'-", 2);
      q = switches[i].part1;
      while ((p = strchr (q, '\'')))
	{
	  obstack_grow (&collect_obstack, q, p - q);
	  obstack_grow (&collect_obstack, "'\\''", 4);
	  q = ++p;
	}
      obstack_grow (&collect_obstack, q, strlen (q));
      obstack_grow (&collect_obstack, "'", 1);

      for (args = switches[i].args; args && *args; args++)
	{
	  obstack_grow (&collect_obstack, " '", 2);
	  q = *args;
	  while ((p = strchr (q, '\'')))
	    {
	      obstack_grow (&collect_obstack, q, p - q);
	      obstack_grow (&collect_obstack, "'\\''", 4);
	      q = ++p;
	    }
	  obstack_grow (&collect_obstack, q, strlen (q));
	  obstack_grow (&collect_obstack, "'", 1);
	}
    }
  obstack_grow (&collect_obstack, "\0", 1);
  putenv (obstack_finish (&collect_obstack));
}
Richard Stallman committed
4151 4152 4153 4154 4155 4156 4157 4158 4159 4160

/* Process a spec string, accumulating and running commands.  */

/* These variables describe the input file name.
   input_file_number is the index on outfiles of this file,
   so that the output file name can be stored for later use by %o.
   input_basename is the start of the part of the input file
   sans all directory names, and basename_length is the number
   of characters starting there excluding the suffix .c or whatever.  */

4161
const char *input_filename;
Richard Stallman committed
4162
static int input_file_number;
4163
size_t input_filename_length;
Richard Stallman committed
4164
static int basename_length;
4165
static int suffixed_basename_length;
4166 4167
static const char *input_basename;
static const char *input_suffix;
4168 4169
static struct stat input_stat;
static int input_stat_set;
Richard Stallman committed
4170

4171 4172 4173
/* The compiler used to process the current input file.  */
static struct compiler *input_file_compiler;

Richard Stallman committed
4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192
/* These are variables used within do_spec and do_spec_1.  */

/* Nonzero if an arg has been started and not yet terminated
   (with space, tab or newline).  */
static int arg_going;

/* Nonzero means %d or %g has been seen; the next arg to be terminated
   is a temporary file name.  */
static int delete_this_arg;

/* Nonzero means %w has been seen; the next arg to be terminated
   is the output file name of this compilation.  */
static int this_is_output_file;

/* Nonzero means %s has been seen; the next arg to be terminated
   is the name of a library file and we should try the standard
   search dirs for it.  */
static int this_is_library_file;

4193 4194 4195
/* Nonzero means that the input of this command is coming from a pipe.  */
static int input_from_pipe;

4196
/* Nonnull means substitute this for any suffix when outputting a switches
4197
   arguments.  */
4198 4199
static const char *suffix_subst;

Richard Stallman committed
4200 4201 4202
/* Process the spec SPEC and run the commands specified therein.
   Returns 0 if the spec is successfully processed; -1 if failed.  */

4203
int
Richard Stallman committed
4204
do_spec (spec)
4205
     const char *spec;
Richard Stallman committed
4206 4207 4208
{
  int value;

4209
  value = do_spec_2 (spec);
Richard Stallman committed
4210 4211 4212 4213 4214 4215 4216 4217

  /* Force out any unfinished command.
     If -pipe, this forces out the last command if it ended in `|'.  */
  if (value == 0)
    {
      if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
	argbuf_index--;

4218 4219
      set_collect_gcc_options ();

Richard Stallman committed
4220 4221 4222 4223 4224 4225 4226
      if (argbuf_index > 0)
	value = execute ();
    }

  return value;
}

4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241
static int
do_spec_2 (spec)
     const char *spec;
{
  clear_args ();
  arg_going = 0;
  delete_this_arg = 0;
  this_is_output_file = 0;
  this_is_library_file = 0;
  input_from_pipe = 0;
  suffix_subst = NULL;

  return do_spec_1 (spec, 0, NULL);
}

4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280

/* Process the given spec string and add any new options to the end
   of the switches/n_switches array.  */

static void
do_self_spec (spec)
     const char *spec;
{
  do_spec_2 (spec);
  do_spec_1 (" ", 0, NULL);

  if (argbuf_index > 0)
    {
      int i, first;

      first = n_switches;
      n_switches += argbuf_index;
      switches = xrealloc (switches,
			   sizeof (struct switchstr) * (n_switches + 1));

      switches[n_switches] = switches[first];
      for (i = 0; i < argbuf_index; i++)
	{
	  struct switchstr *sw;

	  /* Each switch should start with '-'.  */
	  if (argbuf[i][0] != '-')
	    abort ();

	  sw = &switches[i + first];
	  sw->part1 = &argbuf[i][1];
	  sw->args = 0;
	  sw->live_cond = SWITCH_OK;
	  sw->validated = 0;
	  sw->ordering = 0;
	}
    }
}

Richard Stallman committed
4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294
/* 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
   newline by default at the end.
   INSWITCH nonzero means don't process %-sequences in SPEC;
   in this case, % is treated as an ordinary character.
   This is used while substituting switches.
   INSWITCH nonzero also causes SPC not to terminate an argument.

   Value is zero unless a line was finished
   and the command on that line reported an error.  */

static int
do_spec_1 (spec, inswitch, soft_matched_part)
4295
     const char *spec;
Richard Stallman committed
4296
     int inswitch;
4297
     const char *soft_matched_part;
Richard Stallman committed
4298
{
4299 4300
  const char *p = spec;
  int c;
Richard Stallman committed
4301
  int i;
4302
  const char *string;
4303
  int value;
Richard Stallman committed
4304

4305
  while ((c = *p++))
Richard Stallman committed
4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329
    /* If substituting a switch, treat all chars like letters.
       Otherwise, NL, SPC, TAB and % are special.  */
    switch (inswitch ? 'a' : c)
      {
      case '\n':
	/* End of line: finish any pending argument,
	   then run the pending command if one has been started.  */
	if (arg_going)
	  {
	    obstack_1grow (&obstack, 0);
	    string = obstack_finish (&obstack);
	    if (this_is_library_file)
	      string = find_file (string);
	    store_arg (string, delete_this_arg, this_is_output_file);
	    if (this_is_output_file)
	      outfiles[input_file_number] = string;
	  }
	arg_going = 0;

	if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
	  {
	    /* A `|' before the newline means use a pipe here,
	       but only if -pipe was specified.
	       Otherwise, execute now and don't pass the `|' as an arg.  */
4330
	    if (use_pipes)
Richard Stallman committed
4331
	      {
4332
		input_from_pipe = 1;
Richard Stallman committed
4333 4334 4335 4336 4337 4338
		break;
	      }
	    else
	      argbuf_index--;
	  }

4339 4340
	set_collect_gcc_options ();

Richard Stallman committed
4341 4342
	if (argbuf_index > 0)
	  {
4343
	    value = execute ();
Richard Stallman committed
4344 4345 4346 4347 4348 4349 4350 4351 4352
	    if (value)
	      return value;
	  }
	/* Reinitialize for a new command, and for a new argument.  */
	clear_args ();
	arg_going = 0;
	delete_this_arg = 0;
	this_is_output_file = 0;
	this_is_library_file = 0;
4353
	input_from_pipe = 0;
Richard Stallman committed
4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397
	break;

      case '|':
	/* 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;
	  }

	/* Use pipe */
	obstack_1grow (&obstack, c);
	arg_going = 1;
	break;

      case '\t':
      case ' ':
	/* Space or tab ends an argument if one is pending.  */
	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;
	  }
	/* Reinitialize for a new argument.  */
	arg_going = 0;
	delete_this_arg = 0;
	this_is_output_file = 0;
	this_is_library_file = 0;
	break;

      case '%':
	switch (c = *p++)
	  {
	  case 0:
4398
	    fatal ("invalid specification!  Bug in cc");
Richard Stallman committed
4399 4400 4401 4402 4403 4404

	  case 'b':
	    obstack_grow (&obstack, input_basename, basename_length);
	    arg_going = 1;
	    break;

4405 4406 4407 4408 4409
	  case 'B':
	    obstack_grow (&obstack, input_basename, suffixed_basename_length);
	    arg_going = 1;
	    break;

Richard Stallman committed
4410 4411 4412 4413 4414
	  case 'd':
	    delete_this_arg = 2;
	    break;

	  /* Dump out the directories specified with LIBRARY_PATH,
4415 4416
	     followed by the absolute directories
	     that we search for startfiles.  */
Richard Stallman committed
4417
	  case 'D':
4418
	    {
4419
	      struct prefix_list *pl = startfile_prefixes.plist;
4420
	      size_t bufsize = 100;
4421 4422
	      char *buffer = (char *) xmalloc (bufsize);
	      int idx;
4423

4424 4425
	      for (; pl; pl = pl->next)
		{
4426
#ifdef RELATIVE_PREFIX_NOT_LINKDIR
4427 4428 4429 4430
		  /* 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
4431
		     at run time.  In particular, stage1 loses.  */
4432
		  if (!IS_ABSOLUTE_PATHNAME (pl->prefix))
4433
		    continue;
4434
#endif
Doug Evans committed
4435
		  /* Try subdirectory if there is one.  */
4436 4437
		  if (multilib_dir != NULL
		      || (pl->os_multilib && multilib_os_dir != NULL))
Doug Evans committed
4438
		    {
4439 4440 4441 4442 4443
		      const char *multi_dir;

		      multi_dir = pl->os_multilib ? multilib_os_dir
						  : multilib_dir;
		      if (machine_suffix && multilib_dir)
Doug Evans committed
4444 4445 4446 4447 4448 4449 4450 4451 4452 4453
			{
			  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))
			    {
4454
			      do_spec_1 ("-L", 0, NULL);
Doug Evans committed
4455
#ifdef SPACE_AFTER_L_OPTION
4456
			      do_spec_1 (" ", 0, NULL);
Doug Evans committed
4457
#endif
4458 4459
			      do_spec_1 (buffer, 1, NULL);
			      do_spec_1 (multilib_dir, 1, NULL);
Doug Evans committed
4460
			      /* Make this a separate argument.  */
4461
			      do_spec_1 (" ", 0, NULL);
Doug Evans committed
4462 4463 4464 4465
			    }
			}
		      if (!pl->require_machine_suffix)
			{
4466
			  if (is_directory (pl->prefix, multi_dir, 1))
Doug Evans committed
4467
			    {
4468
			      do_spec_1 ("-L", 0, NULL);
Doug Evans committed
4469
#ifdef SPACE_AFTER_L_OPTION
4470
			      do_spec_1 (" ", 0, NULL);
Doug Evans committed
4471
#endif
4472
			      do_spec_1 (pl->prefix, 1, NULL);
4473
			      do_spec_1 (multi_dir, 1, NULL);
Doug Evans committed
4474
			      /* Make this a separate argument.  */
4475
			      do_spec_1 (" ", 0, NULL);
Doug Evans committed
4476 4477 4478
			    }
			}
		    }
4479 4480
		  if (machine_suffix)
		    {
4481
		      if (is_directory (pl->prefix, machine_suffix, 1))
4482
			{
4483
			  do_spec_1 ("-L", 0, NULL);
4484
#ifdef SPACE_AFTER_L_OPTION
4485
			  do_spec_1 (" ", 0, NULL);
4486
#endif
4487
			  do_spec_1 (pl->prefix, 1, NULL);
4488 4489 4490 4491 4492 4493
			  /* 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);
4494
			  if (IS_DIR_SEPARATOR (buffer[idx - 1]))
4495
			    buffer[idx - 1] = 0;
4496
			  do_spec_1 (buffer, 1, NULL);
4497
			  /* Make this a separate argument.  */
4498
			  do_spec_1 (" ", 0, NULL);
4499 4500 4501 4502
			}
		    }
		  if (!pl->require_machine_suffix)
		    {
4503
		      if (is_directory (pl->prefix, "", 1))
4504
			{
4505
			  do_spec_1 ("-L", 0, NULL);
4506
#ifdef SPACE_AFTER_L_OPTION
4507
			  do_spec_1 (" ", 0, NULL);
4508
#endif
4509 4510 4511 4512 4513 4514
			  /* 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);
4515
			  if (IS_DIR_SEPARATOR (buffer[idx - 1]))
4516
			    buffer[idx - 1] = 0;
4517
			  do_spec_1 (buffer, 1, NULL);
4518
			  /* Make this a separate argument.  */
4519
			  do_spec_1 (" ", 0, NULL);
4520 4521 4522 4523 4524
			}
		    }
		}
	      free (buffer);
	    }
Richard Stallman committed
4525 4526 4527
	    break;

	  case 'e':
4528
	    /* %efoo means report an error with `foo' as error message
Richard Stallman committed
4529 4530
	       and don't execute any more commands for this file.  */
	    {
4531
	      const char *q = p;
Richard Stallman committed
4532
	      char *buf;
Kazu Hirata committed
4533 4534
	      while (*p != 0 && *p != '\n')
		p++;
Richard Stallman committed
4535 4536 4537
	      buf = (char *) alloca (p - q + 1);
	      strncpy (buf, q, p - q);
	      buf[p - q] = 0;
4538
	      error ("%s", buf);
Richard Stallman committed
4539 4540 4541
	      return -1;
	    }
	    break;
4542
	  case 'n':
4543
	    /* %nfoo means report a notice with `foo' on stderr.  */
4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556
	    {
	      const char *q = p;
	      char *buf;
	      while (*p != 0 && *p != '\n')
		p++;
	      buf = (char *) alloca (p - q + 1);
	      strncpy (buf, q, p - q);
	      buf[p - q] = 0;
	      notice ("%s\n", buf);
	      if (*p)
		p++;
	    }
	    break;
Richard Stallman committed
4557

Kazu Hirata committed
4558 4559 4560 4561
	  case 'j':
	    {
	      struct stat st;

4562 4563 4564 4565
	      /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
		 defined, and it is not a directory, and it is
		 writable, use it.  Otherwise, treat this like any
		 other temporary file.  */
Kazu Hirata committed
4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577

	      if ((!save_temps_flag)
		  && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
		  && (access (HOST_BIT_BUCKET, W_OK) == 0))
		{
		  obstack_grow (&obstack, HOST_BIT_BUCKET,
				strlen (HOST_BIT_BUCKET));
		  delete_this_arg = 0;
		  arg_going = 1;
		  break;
		}
	    }
4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606
	    goto create_temp_file;
	  case '|':
	    if (use_pipes)
	      {
		obstack_1grow (&obstack, '-');
		delete_this_arg = 0;
		arg_going = 1;

		/* consume suffix */
		while (*p == '.' || ISALPHA ((unsigned char) *p))
		  p++;
		if (p[0] == '%' && p[1] == 'O')
		  p += 2;
		
		break;
	      }
	    goto create_temp_file;
	  case 'm':
	    if (use_pipes)
	      {
		/* consume suffix */
		while (*p == '.' || ISALPHA ((unsigned char) *p))
		  p++;
		if (p[0] == '%' && p[1] == 'O')
		  p += 2;
		
		break;
	      }
	    goto create_temp_file;
Richard Stallman committed
4607
	  case 'g':
Tom Wood committed
4608
	  case 'u':
4609
	  case 'U':
4610
	  create_temp_file:
Richard Stallman committed
4611
	      {
Tom Wood committed
4612
		struct temp_name *t;
4613
		int suffix_length;
4614
		const char *suffix = p;
4615
		char *saved_suffix = NULL;
4616

Kazu Hirata committed
4617
		while (*p == '.' || ISALPHA ((unsigned char) *p))
4618 4619
		  p++;
		suffix_length = p - suffix;
4620 4621
		if (p[0] == '%' && p[1] == 'O')
		  {
4622
		    p += 2;
4623
		    /* We don't support extra suffix characters after %O.  */
Kazu Hirata committed
4624
		    if (*p == '.' || ISALPHA ((unsigned char) *p))
4625
		      abort ();
4626
		    if (suffix_length == 0)
4627
		      suffix = TARGET_OBJECT_SUFFIX;
4628 4629 4630 4631
		    else
		      {
			saved_suffix
			  = (char *) xmalloc (suffix_length
4632
					      + strlen (TARGET_OBJECT_SUFFIX));
4633 4634
			strncpy (saved_suffix, suffix, suffix_length);
			strcpy (saved_suffix + suffix_length,
4635
				TARGET_OBJECT_SUFFIX);
4636
		      }
4637
		    suffix_length += strlen (TARGET_OBJECT_SUFFIX);
4638
		  }
4639

4640 4641 4642 4643 4644 4645 4646
		/* If the input_filename has the same suffix specified
		   for the %g, %u, or %U, and -save-temps is specified,
		   we could end up using that file as an intermediate
		   thus clobbering the user's source file (.e.g.,
		   gcc -save-temps foo.s would clobber foo.s with the
		   output of cpp0).  So check for this condition and
		   generate a temp file as the intermediate.  */
4647

4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658
		if (save_temps_flag)
		  {
		    temp_filename_length = basename_length + suffix_length;
		    temp_filename = alloca (temp_filename_length + 1);
		    strncpy ((char *) temp_filename, input_basename, basename_length);
		    strncpy ((char *) temp_filename + basename_length, suffix,
		    	     suffix_length);
		    *((char *) temp_filename + temp_filename_length) = '\0';
		    if (strcmp (temp_filename, input_filename) != 0)
		      {
		      	struct stat st_temp;
4659

4660 4661 4662 4663 4664 4665 4666
		      	/* 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;
		      	  }
4667

4668 4669 4670 4671
		      	/* 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.  */
4672

4673 4674 4675 4676
			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)
4677
			  {
4678 4679 4680 4681 4682
			    temp_filename = save_string (temp_filename,
							 temp_filename_length + 1);
			    obstack_grow (&obstack, temp_filename,
			    			    temp_filename_length);
			    arg_going = 1;
4683
			    delete_this_arg = 0;
4684 4685 4686 4687
			    break;
			  }
		      }
		  }
Tom Wood committed
4688 4689 4690 4691

		/* See if we already have an association of %g/%u/%U and
		   suffix.  */
		for (t = temp_names; t; t = t->next)
4692 4693
		  if (t->length == suffix_length
		      && strncmp (t->suffix, suffix, suffix_length) == 0
4694
		      && t->unique == (c == 'u' || c == 'j'))
Tom Wood committed
4695 4696
		    break;

4697 4698
		/* Make a new association if needed.  %u and %j
		   require one.  */
4699
		if (t == 0 || c == 'u' || c == 'j')
Tom Wood committed
4700 4701 4702 4703 4704 4705 4706
		  {
		    if (t == 0)
		      {
			t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
			t->next = temp_names;
			temp_names = t;
		      }
4707
		    t->length = suffix_length;
4708 4709 4710 4711 4712 4713 4714
		    if (saved_suffix)
		      {
			t->suffix = saved_suffix;
			saved_suffix = NULL;
		      }
		    else
		      t->suffix = save_string (suffix, suffix_length);
4715
		    t->unique = (c == 'u' || c == 'j');
4716
		    temp_filename = make_temp_file (t->suffix);
4717
		    temp_filename_length = strlen (temp_filename);
Tom Wood committed
4718 4719 4720 4721
		    t->filename = temp_filename;
		    t->filename_length = temp_filename_length;
		  }

4722 4723 4724
		if (saved_suffix)
		  free (saved_suffix);

Tom Wood committed
4725
		obstack_grow (&obstack, t->filename, t->filename_length);
4726
		delete_this_arg = 1;
Richard Stallman committed
4727 4728 4729 4730 4731 4732 4733 4734 4735
	      }
	    arg_going = 1;
	    break;

	  case 'i':
	    obstack_grow (&obstack, input_filename, input_filename_length);
	    arg_going = 1;
	    break;

4736
	  case 'I':
4737
	    {
4738
	      struct prefix_list *pl = include_prefixes.plist;
4739 4740 4741

	      if (gcc_exec_prefix)
		{
4742
		  do_spec_1 ("-iprefix", 1, NULL);
4743
		  /* Make this a separate argument.  */
4744 4745 4746
		  do_spec_1 (" ", 0, NULL);
		  do_spec_1 (gcc_exec_prefix, 1, NULL);
		  do_spec_1 (" ", 0, NULL);
4747 4748 4749 4750
		}

	      for (; pl; pl = pl->next)
		{
4751
		  do_spec_1 ("-isystem", 1, NULL);
4752
		  /* Make this a separate argument.  */
4753 4754 4755
		  do_spec_1 (" ", 0, NULL);
		  do_spec_1 (pl->prefix, 1, NULL);
		  do_spec_1 (" ", 0, NULL);
4756 4757
		}
	    }
4758 4759
	    break;

Richard Stallman committed
4760
	  case 'o':
4761 4762 4763
	    {
	      int max = n_infiles;
	      max += lang_specific_extra_outfiles;
4764

4765 4766 4767 4768 4769
	      for (i = 0; i < max; i++)
		if (outfiles[i])
		  store_arg (outfiles[i], 0, 0);
	      break;
	    }
Richard Stallman committed
4770

4771
	  case 'O':
4772
	    obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
4773 4774 4775
	    arg_going = 1;
	    break;

Richard Stallman committed
4776 4777 4778 4779
	  case 's':
	    this_is_library_file = 1;
	    break;

4780 4781 4782 4783
	  case 'V':
	    outfiles[input_file_number] = NULL;
	    break;

Richard Stallman committed
4784 4785 4786 4787 4788 4789
	  case 'w':
	    this_is_output_file = 1;
	    break;

	  case 'W':
	    {
4790
	      int cur_index = argbuf_index;
Richard Stallman committed
4791 4792 4793 4794 4795 4796
	      /* Handle the {...} following the %W.  */
	      if (*p != '{')
		abort ();
	      p = handle_braces (p + 1);
	      if (p == 0)
		return -1;
4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808
	      /* 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;
		}
Richard Stallman committed
4809 4810
	      /* If any args were output, mark the last one for deletion
		 on failure.  */
4811
	      if (argbuf_index != cur_index)
Richard Stallman committed
4812 4813 4814 4815 4816 4817 4818
		record_temp_file (argbuf[argbuf_index - 1], 0, 1);
	      break;
	    }

	  /* %x{OPTION} records OPTION for %X to output.  */
	  case 'x':
	    {
4819
	      const char *p1 = p;
Richard Stallman committed
4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837
	      char *string;

	      /* Skip past the option value and make a copy.  */
	      if (*p != '{')
		abort ();
	      while (*p++ != '}')
		;
	      string = save_string (p1 + 1, p - p1 - 2);

	      /* See if we already recorded this option.  */
	      for (i = 0; i < n_linker_options; i++)
		if (! strcmp (string, linker_options[i]))
		  {
		    free (string);
		    return 0;
		  }

	      /* This option is new; add it.  */
Nick Clifton committed
4838
	      add_linker_option (string, strlen (string));
Richard Stallman committed
4839 4840 4841
	    }
	    break;

4842
	  /* Dump out the options accumulated previously using %x.  */
Richard Stallman committed
4843 4844 4845
	  case 'X':
	    for (i = 0; i < n_linker_options; i++)
	      {
4846
		do_spec_1 (linker_options[i], 1, NULL);
Richard Stallman committed
4847
		/* Make each accumulated option a separate argument.  */
4848
		do_spec_1 (" ", 0, NULL);
Richard Stallman committed
4849 4850 4851
	      }
	    break;

4852 4853 4854 4855
	  /* Dump out the options accumulated previously using -Wa,.  */
	  case 'Y':
	    for (i = 0; i < n_assembler_options; i++)
	      {
4856
		do_spec_1 (assembler_options[i], 1, NULL);
4857
		/* Make each accumulated option a separate argument.  */
4858
		do_spec_1 (" ", 0, NULL);
4859 4860 4861
	      }
	    break;

4862 4863 4864 4865
	  /* Dump out the options accumulated previously using -Wp,.  */
	  case 'Z':
	    for (i = 0; i < n_preprocessor_options; i++)
	      {
4866
		do_spec_1 (preprocessor_options[i], 1, NULL);
4867
		/* Make each accumulated option a separate argument.  */
4868
		do_spec_1 (" ", 0, NULL);
4869 4870 4871
	      }
	    break;

4872
	    /* Here are digits and numbers that just process
Richard Stallman committed
4873 4874 4875
	       a certain constant string as a spec.  */

	  case '1':
4876
	    value = do_spec_1 (cc1_spec, 0, NULL);
4877 4878
	    if (value != 0)
	      return value;
Richard Stallman committed
4879 4880 4881
	    break;

	  case '2':
4882
	    value = do_spec_1 (cc1plus_spec, 0, NULL);
4883 4884
	    if (value != 0)
	      return value;
Richard Stallman committed
4885 4886 4887
	    break;

	  case 'a':
4888
	    value = do_spec_1 (asm_spec, 0, NULL);
4889 4890
	    if (value != 0)
	      return value;
Richard Stallman committed
4891 4892 4893
	    break;

	  case 'A':
4894
	    value = do_spec_1 (asm_final_spec, 0, NULL);
4895 4896
	    if (value != 0)
	      return value;
Richard Stallman committed
4897 4898 4899
	    break;

	  case 'C':
4900
	    {
4901
	      const char *const spec
4902 4903
		= (input_file_compiler->cpp_spec
		   ? input_file_compiler->cpp_spec
4904
		   : cpp_spec);
4905
	      value = do_spec_1 (spec, 0, NULL);
4906 4907 4908
	      if (value != 0)
		return value;
	    }
Richard Stallman committed
4909 4910 4911
	    break;

	  case 'E':
4912
	    value = do_spec_1 (endfile_spec, 0, NULL);
4913 4914
	    if (value != 0)
	      return value;
Richard Stallman committed
4915 4916 4917
	    break;

	  case 'l':
4918
	    value = do_spec_1 (link_spec, 0, NULL);
4919 4920
	    if (value != 0)
	      return value;
Richard Stallman committed
4921 4922 4923
	    break;

	  case 'L':
4924
	    value = do_spec_1 (lib_spec, 0, NULL);
4925 4926
	    if (value != 0)
	      return value;
Richard Stallman committed
4927 4928
	    break;

Jason Merrill committed
4929
	  case 'G':
4930
	    value = do_spec_1 (libgcc_spec, 0, NULL);
Jason Merrill committed
4931 4932 4933 4934
	    if (value != 0)
	      return value;
	    break;

4935 4936 4937 4938 4939 4940 4941 4942 4943
	  case 'M':
	    if (multilib_dir && strcmp (multilib_dir, ".") != 0)
	      {
		char *p;
		const char *q;
		size_t len;

		len = strlen (multilib_dir);
		obstack_blank (&obstack, len + 1);
4944
		p = obstack_next_free (&obstack) - (len + 1);
4945 4946 4947 4948 4949 4950 4951

		*p++ = '_';
		for (q = multilib_dir; *q ; ++q, ++p)
		  *p = (IS_DIR_SEPARATOR (*q) ? '_' : *q);
	      }
	    break;

Richard Stallman committed
4952 4953 4954 4955
	  case 'p':
	    {
	      char *x = (char *) alloca (strlen (cpp_predefines) + 1);
	      char *buf = x;
Zack Weinberg committed
4956
	      const char *y;
Richard Stallman committed
4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975

	      /* 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;

4976
	      value = do_spec_1 (buf, 0, NULL);
4977 4978
	      if (value != 0)
		return value;
Richard Stallman committed
4979 4980 4981 4982 4983 4984 4985
	    }
	    break;

	  case 'P':
	    {
	      char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
	      char *buf = x;
Zack Weinberg committed
4986
	      const char *y;
Richard Stallman committed
4987 4988

	      /* Copy all of CPP_PREDEFINES into BUF,
4989 4990
		 but force them all into the reserved name space if they
		 aren't already there.  The reserved name space is all
4991 4992 4993 4994 4995
		 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__.  */
Richard Stallman committed
4996 4997 4998 4999 5000 5001 5002 5003 5004 5005
	      y = cpp_predefines;
	      while (*y != 0)
		{
		  if (! strncmp (y, "-D", 2))
		    {
		      int flag = 0;

		      *x++ = *y++;
		      *x++ = *y++;

5006
		      if (*y != '_'
Kazu Hirata committed
5007 5008 5009
			  || (*(y + 1) != '_'
			      && ! ISUPPER ((unsigned char) *(y + 1))))
			{
Richard Stallman committed
5010
			  /* Stick __ at front of macro name.  */
5011 5012
			  if (*y != '_')
			    *x++ = '_';
Richard Stallman committed
5013 5014 5015 5016 5017 5018 5019 5020 5021 5022
			  *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)
Kazu Hirata committed
5023
			{
5024 5025 5026 5027 5028 5029
			  if (x[-1] != '_')
			    {
			      if (x[-2] != '_')
				*x++ = '_';
			      *x++ = '_';
			    }
Richard Stallman committed
5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051
			}

		      /* 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))
		    {
5052
		      y += 2;
Richard Stallman committed
5053

5054
		      if (*y != '_'
Kazu Hirata committed
5055 5056 5057
			  || (*(y + 1) != '_'
			      && ! ISUPPER ((unsigned char) *(y + 1))))
			{
5058 5059 5060
			  /* Stick -D__ at front of macro name.  */
			  *x++ = '-';
			  *x++ = 'D';
5061 5062
			  if (*y != '_')
			    *x++ = '_';
Richard Stallman committed
5063 5064
			  *x++ = '_';

5065 5066 5067
			  /* Copy the macro name.  */
			  while (*y && *y != '=' && *y != ' ' && *y != '\t')
			    *x++ = *y++;
Richard Stallman committed
5068

5069 5070 5071 5072 5073 5074 5075 5076 5077 5078
			  /* 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++;
			}
Richard Stallman committed
5079 5080 5081 5082
		    }
		  else if (*y == ' ' || *y == '\t')
		    /* Copy whitespace to the result.  */
		    *x++ = *y++;
5083
		  /* Don't copy -A options.  */
Richard Stallman committed
5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106
		  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;

5107
	      value = do_spec_1 (buf, 0, NULL);
5108 5109
	      if (value != 0)
		return value;
Richard Stallman committed
5110 5111 5112
	    }
	    break;

5113 5114 5115 5116 5117 5118 5119 5120
	  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));
	    break;

Richard Stallman committed
5121
	  case 'S':
5122
	    value = do_spec_1 (startfile_spec, 0, NULL);
5123 5124
	    if (value != 0)
	      return value;
Richard Stallman committed
5125 5126 5127 5128 5129 5130 5131 5132 5133 5134
	    break;

	    /* Here we define characters other than letters and digits.  */

	  case '{':
	    p = handle_braces (p);
	    if (p == 0)
	      return -1;
	    break;

5135 5136 5137 5138 5139 5140
	  case ':':
	    p = handle_spec_function (p);
	    if (p == 0)
	      return -1;
	    break;

Richard Stallman committed
5141 5142 5143 5144
	  case '%':
	    obstack_1grow (&obstack, '%');
	    break;

5145 5146 5147
	  case '.':
	    {
	      unsigned len = 0;
5148

5149 5150 5151 5152 5153
	      while (p[len] && p[len] != ' ' && p[len] != '%')
		len++;
	      suffix_subst = save_string (p - 1, len + 1);
	      p += len;
	    }
5154
	   break;
5155

5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181
	   /* Henceforth ignore the option(s) matching the pattern
	      after the %<.  */
	  case '<':
	    {
	      unsigned len = 0;
	      int have_wildcard = 0;
	      int i;

	      while (p[len] && p[len] != ' ' && p[len] != '\t')
		len++;

	      if (p[len-1] == '*')
		have_wildcard = 1;

	      for (i = 0; i < n_switches; i++)
		if (!strncmp (switches[i].part1, p, len - have_wildcard)
		    && (have_wildcard || switches[i].part1[len] == '\0'))
		  {
		    switches[i].live_cond = SWITCH_IGNORE;
		    switches[i].validated = 1;
		  }

	      p += len;
	    }
	    break;

Richard Stallman committed
5182
	  case '*':
5183 5184
	    if (soft_matched_part)
	      {
5185 5186
		do_spec_1 (soft_matched_part, 1, NULL);
		do_spec_1 (" ", 0, NULL);
5187 5188 5189 5190 5191
	      }
	    else
	      /* Catch the case where a spec string contains something like
		 '%{foo:%*}'.  ie there is no * in the pattern on the left
		 hand side of the :.  */
5192
	      error ("spec failure: '%%*' has not been initialized by pattern match");
Richard Stallman committed
5193 5194 5195 5196
	    break;

	    /* Process a string found as the value of a spec given by name.
	       This feature allows individual machine descriptions
5197 5198 5199 5200
	       to add and use their own specs.
	       %[...] modifies -D options the way %P does;
	       %(...) uses the spec unmodified.  */
	  case '[':
5201
	    error ("warning: use of obsolete %%[ operator in specs");
Richard Stallman committed
5202 5203
	  case '(':
	    {
5204
	      const char *name = p;
Richard Stallman committed
5205 5206 5207 5208
	      struct spec_list *sl;
	      int len;

	      /* The string after the S/P is the name of a spec that is to be
Mike Stump committed
5209
		 processed.  */
5210
	      while (*p && *p != ')' && *p != ']')
Richard Stallman committed
5211 5212
		p++;

5213
	      /* See if it's in the list.  */
Richard Stallman committed
5214
	      for (len = p - name, sl = specs; sl; sl = sl->next)
Michael Meissner committed
5215
		if (sl->name_len == len && !strncmp (sl->name, name, len))
Richard Stallman committed
5216
		  {
Michael Meissner committed
5217
		    name = *(sl->ptr_spec);
5218
#ifdef DEBUG_SPECS
5219 5220
		    notice ("Processing spec %c%s%c, which is '%s'\n",
			    c, sl->name, (c == '(') ? ')' : ']', name);
5221
#endif
Richard Stallman committed
5222 5223 5224 5225 5226
		    break;
		  }

	      if (sl)
		{
5227 5228
		  if (c == '(')
		    {
5229
		      value = do_spec_1 (name, 0, NULL);
5230 5231 5232 5233 5234 5235 5236
		      if (value != 0)
			return value;
		    }
		  else
		    {
		      char *x = (char *) alloca (strlen (name) * 2 + 1);
		      char *buf = x;
5237
		      const char *y = name;
5238 5239 5240
		      int flag = 0;

		      /* Copy all of NAME into BUF, but put __ after
5241
			 every -D and at the end of each arg.  */
5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253
		      while (1)
			{
			  if (! strncmp (y, "-D", 2))
			    {
			      *x++ = '-';
			      *x++ = 'D';
			      *x++ = '_';
			      *x++ = '_';
			      y += 2;
			      flag = 1;
			      continue;
			    }
Kazu Hirata committed
5254 5255 5256
			  else if (flag
				   && (*y == ' ' || *y == '\t' || *y == '='
				       || *y == '}' || *y == 0))
5257 5258 5259 5260 5261
			    {
			      *x++ = '_';
			      *x++ = '_';
			      flag = 0;
			    }
Kazu Hirata committed
5262
			  if (*y == 0)
5263 5264 5265 5266 5267 5268
			    break;
			  else
			    *x++ = *y++;
			}
		      *x = 0;

5269
		      value = do_spec_1 (buf, 0, NULL);
5270 5271 5272
		      if (value != 0)
			return value;
		    }
Richard Stallman committed
5273
		}
5274

5275
	      /* Discard the closing paren or bracket.  */
5276 5277
	      if (*p)
		p++;
Richard Stallman committed
5278 5279 5280
	    }
	    break;

5281 5282
	  case 'v':
	    {
5283
	      int c1 = *p++;  /* Select first or second version number.  */
Zack Weinberg committed
5284 5285
	      const char *v = compiler_version;
	      const char *q;
5286
	      static const char zeroc = '0';
5287 5288 5289 5290 5291

	      /* 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".  */
5292
	      while (! ISDIGIT (*v))
5293 5294 5295 5296
		v++;
	      if (v > compiler_version && v[-1] != '-')
		abort ();

5297
	      /* If desired, advance to second version number.  */
5298
	      if (c1 >= '2')
5299
		{
5300
		  /* Set V after the first period.  */
5301
		  while (ISDIGIT (*v))
5302
		    v++;
5303 5304 5305
		  if (*v != '.')
		    abort ();
		  v++;
5306
		}
5307

5308 5309 5310 5311 5312 5313 5314 5315 5316
	      /* 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 ();
Kazu Hirata committed
5317 5318
		  if (*v != 0)
		    v++;
5319 5320
		}

5321
	      /* Set Q at the next period or at the end.  */
5322
	      q = v;
5323
	      while (ISDIGIT (*q))
5324
		q++;
Michael Meissner committed
5325
	      if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
5326 5327
		abort ();

Kazu Hirata committed
5328 5329 5330 5331 5332 5333
	      if (q > v)
		/* Put that part into the command.  */
		obstack_grow (&obstack, v, q - v);
	      else
		/* Default to "0" */
		obstack_grow (&obstack, &zeroc, 1);
5334 5335 5336 5337
	      arg_going = 1;
	    }
	    break;

Richard Stallman committed
5338
	  default:
5339
	    error ("spec failure: unrecognized spec option '%c'", c);
5340
	    break;
Richard Stallman committed
5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354
	  }
	break;

      case '\\':
	/* Backslash: treat next character as ordinary.  */
	c = *p++;

	/* fall through */
      default:
	/* Ordinary character: put it into the current argument.  */
	obstack_1grow (&obstack, c);
	arg_going = 1;
      }

5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368
  /* End of string.  If we are processing a spec function, we need to
     end any pending argument.  */
  if (processing_spec_function && 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;
    }

Kazu Hirata committed
5369
  return 0;
Richard Stallman committed
5370 5371
}

5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527
/* Look up a spec function.  */

static const struct spec_function *
lookup_spec_function (name)
     const char *name;
{
  static const struct spec_function * const spec_function_tables[] =
  {
    static_spec_functions,
    lang_specific_spec_functions,
  };
  const struct spec_function *sf;
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (spec_function_tables); i++)
    {
      for (sf = spec_function_tables[i]; sf->name != NULL; sf++)
	if (strcmp (sf->name, name) == 0)
	  return sf;
    }

  return NULL;
}

/* Evaluate a spec function.  */

static const char *
eval_spec_function (func, args)
     const char *func, *args;
{
  const struct spec_function *sf;
  const char *funcval;

  /* Saved spec processing context.  */
  int save_argbuf_index;
  int save_argbuf_length;
  const char **save_argbuf;

  int save_arg_going;
  int save_delete_this_arg;
  int save_this_is_output_file;
  int save_this_is_library_file;
  int save_input_from_pipe;
  const char *save_suffix_subst;


  sf = lookup_spec_function (func);
  if (sf == NULL)
    fatal ("unknown spec function `%s'", func);

  /* Push the spec processing context.  */
  save_argbuf_index = argbuf_index;
  save_argbuf_length = argbuf_length;
  save_argbuf = argbuf;

  save_arg_going = arg_going;
  save_delete_this_arg = delete_this_arg;
  save_this_is_output_file = this_is_output_file;
  save_this_is_library_file = this_is_library_file;
  save_input_from_pipe = input_from_pipe;
  save_suffix_subst = suffix_subst;

  /* Create a new spec processing context, and build the function
     arguments.  */

  alloc_args ();
  if (do_spec_2 (args) < 0)
    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.  */

  funcval = (*sf->func) (argbuf_index, argbuf);

  /* Pop the spec processing context.  */
  argbuf_index = save_argbuf_index;
  argbuf_length = save_argbuf_length;
  free (argbuf);
  argbuf = save_argbuf;

  arg_going = save_arg_going;
  delete_this_arg = save_delete_this_arg;
  this_is_output_file = save_this_is_output_file;
  this_is_library_file = save_this_is_library_file;
  input_from_pipe = save_input_from_pipe;
  suffix_subst = save_suffix_subst;

  return funcval;
}

/* Handle a spec function call of the form:

   %:function(args)

   ARGS is processed as a spec in a separate context and split into an
   argument vector in the normal fashion.  The function returns a string
   containing a spec which we then process in the caller's context, or
   NULL if no processing is required.  */

static const char *
handle_spec_function (p)
     const char *p;
{
  char *func, *args;
  const char *endp, *funcval;
  int count;

  processing_spec_function++;

  /* Get the function name.  */
  for (endp = p; *endp != '\0'; endp++)
    {
      if (*endp == '(')		/* ) */
        break;
      /* Only allow [A-Za-z0-9], -, and _ in function names.  */
      if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
	fatal ("malformed spec function name");
    }
  if (*endp != '(')		/* ) */
    fatal ("no arguments for spec function");
  func = save_string (p, endp - p);
  p = ++endp;

  /* Get the arguments.  */
  for (count = 0; *endp != '\0'; endp++)
    {
      /* ( */
      if (*endp == ')')
	{
	  if (count == 0)
	    break;
	  count--;
	}
      else if (*endp == '(')	/* ) */
	count++;
    }
  /* ( */
  if (*endp != ')')
    fatal ("malformed spec function arguments");
  args = save_string (p, endp - p);
  p = ++endp;

  /* p now points to just past the end of the spec function expression.  */

  funcval = eval_spec_function (func, args);
  if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
    p = NULL;

  free (func);
  free (args);

  processing_spec_function--;

  return p;
}

5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538
/* 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;
{
  return (input_suffix
	  && !strncmp (input_suffix, atom, end_atom - atom)
	  && input_suffix[end_atom - atom] == '\0');
}
Richard Stallman committed
5539

5540 5541 5542 5543 5544 5545 5546 5547
/* Inline subroutine of handle_braces.  Returns true if a switch
   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;
Richard Stallman committed
5548
{
5549 5550 5551
  int i;
  int len = end_atom - atom;
  int plen = starred ? len : -1;
Richard Stallman committed
5552

5553 5554 5555 5556 5557
  for (i = 0; i < n_switches; i++)
    if (!strncmp (switches[i].part1, atom, len)
	&& (starred || switches[i].part1[len] == '\0')
	&& check_live_switch (i, plen))
      return true;
5558

5559 5560
  return false;
}
Richard Stallman committed
5561

5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580
/* Inline subroutine of handle_braces.  Mark all of the switches which
   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;
{
  int i;
  int len = end_atom - atom;
  int plen = starred ? len : -1;

  for (i = 0; i < n_switches; i++)
    if (!strncmp (switches[i].part1, atom, len)
	&& (starred || switches[i].part1[len] == '\0')
	&& check_live_switch (i, plen))
      switches[i].ordering = 1;
}
5581

5582 5583 5584 5585 5586 5587
/* Inline subroutine of handle_braces.  Process all the currently
   marked switches through give_switch, and clear the marks.  */
static inline void
process_marked_switches ()
{
  int i;
Richard Stallman committed
5588

5589 5590 5591 5592 5593 5594 5595
  for (i = 0; i < n_switches; i++)
    if (switches[i].ordering == 1)
      {
	switches[i].ordering = 0;
	give_switch (i, 0);
      }
}
Richard Stallman committed
5596

5597 5598 5599
/* Handle a %{ ... } construct.  P points just inside the leading {.
   Returns a pointer one past the end of the brace block, or 0
   if we call do_spec_1 and that returns -1.  */
Richard Stallman committed
5600

5601 5602 5603 5604 5605 5606
static const char *
handle_braces (p)
     const char *p;
{
  const char *atom, *end_atom;
  const char *d_atom = NULL, *d_end_atom = NULL;
5607

5608 5609 5610 5611
  bool a_is_suffix;
  bool a_is_starred;
  bool a_is_negated;
  bool a_matched;
5612

5613 5614 5615 5616 5617 5618 5619 5620 5621
  bool a_must_be_last = false;
  bool ordered_set    = false;
  bool disjunct_set   = false;
  bool disj_matched   = false;
  bool disj_starred   = true;
  bool n_way_choice   = false;
  bool n_way_matched  = false;

#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
5622

5623
  do
Richard Stallman committed
5624
    {
5625 5626
      if (a_must_be_last)
	abort ();
5627

5628 5629 5630
      /* Scan one "atom" (S in the description above of %{}, possibly
	 with !, ., or * modifiers).  */
      a_matched = a_is_suffix = a_is_starred = a_is_negated = false;
Kazu Hirata committed
5631

5632 5633 5634
      SKIP_WHITE();
      if (*p == '!')
	p++, a_is_negated = true;
Richard Stallman committed
5635

5636 5637 5638
      SKIP_WHITE();
      if (*p == '.')
	p++, a_is_suffix = true;
Richard Stallman committed
5639

5640 5641
      atom = p;
      while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
5642
	     || *p == ',' || *p == '.' || *p == '@')
5643 5644
	p++;
      end_atom = p;
Richard Stallman committed
5645

5646 5647
      if (*p == '*')
	p++, a_is_starred = 1;
5648

5649 5650 5651 5652 5653 5654 5655 5656
      SKIP_WHITE();
      if (*p == '&' || *p == '}')
	{
	  /* 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 ();
Richard Stallman committed
5657

5658 5659 5660 5661 5662 5663
	  mark_matching_switches (atom, end_atom, a_is_starred);

	  if (*p == '}')
	    process_marked_switches ();
	}
      else if (*p == '|' || *p == ':')
Richard Stallman committed
5664
	{
5665 5666 5667 5668 5669
	  /* Substitute some text if the current atom appears as a switch
	     or suffix.  */
	  disjunct_set = true;
	  if (ordered_set)
	    abort ();
Richard Stallman committed
5670

5671
	  if (atom == end_atom)
Richard Stallman committed
5672
	    {
5673 5674 5675 5676 5677 5678 5679 5680 5681
	      if (!n_way_choice || disj_matched || *p == '|'
		  || a_is_negated || a_is_suffix || a_is_starred)
		abort ();

	      /* An empty term may appear as the last choice of an
		 N-way choice set; it means "otherwise".  */
	      a_must_be_last = true;
	      disj_matched = !n_way_matched;
	      disj_starred = false;
Richard Stallman committed
5682
	    }
5683
	  else
Richard Stallman committed
5684
	    {
5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706
	       if (a_is_suffix && a_is_starred)
		 abort ();

	       if (!a_is_starred)
		 disj_starred = false;

	       /* Don't bother testing this atom if we already have a
                  match.  */
	       if (!disj_matched && !n_way_matched)
		 {
		   if (a_is_suffix)
		     a_matched = input_suffix_matches (atom, end_atom);
		   else
		     a_matched = switch_matches (atom, end_atom, a_is_starred);

		   if (a_matched != a_is_negated)
		     {
		       disj_matched = true;
		       d_atom = atom;
		       d_end_atom = end_atom;
		     }
		 }
Richard Stallman committed
5707 5708
	    }

5709
	  if (*p == ':')
Richard Stallman committed
5710
	    {
5711 5712 5713 5714 5715 5716
	      /* Found the body, that is, the text to substitute if the
		 current disjunction matches.  */
	      p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
				      disj_matched && !n_way_matched);
	      if (p == 0)
		return 0;
Richard Stallman committed
5717

5718 5719 5720
	      /* If we have an N-way choice, reset state for the next
		 disjunction.  */
	      if (*p == ';')
Richard Stallman committed
5721
		{
5722 5723 5724 5725 5726
		  n_way_choice = true;
		  n_way_matched |= disj_matched;
		  disj_matched = false;
		  disj_starred = true;
		  d_atom = d_end_atom = NULL;
Richard Stallman committed
5727 5728 5729 5730
		}
	    }
	}
      else
5731 5732 5733
	abort ();
    }
  while (*p++ != '}');
Richard Stallman committed
5734

5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770
  return p;

#undef SKIP_WHITE
}

/* Subroutine of handle_braces.  Scan and process a brace substitution body
   (X in the description of %{} syntax).  P points one past the colon;
   ATOM and END_ATOM bracket the first atom which was found to be true
   (present) in the current disjunction; STARRED indicates whether all
   the atoms in the current disjunction were starred (for syntax validation);
   MATCHED indicates whether the disjunction matched or not, and therefore
   whether or not the body is to be processed through do_spec_1 or just
   skipped.  Returns a pointer to the closing } or ;, or 0 if do_spec_1
   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;
{
  const char *body, *end_body;
  unsigned int nesting_level;
  bool have_subst     = false;

  /* Locate the closing } or ;, honoring nested braces.
     Trim trailing whitespace.  */
  body = p;
  nesting_level = 1;
  for (;;)
    {
      if (*p == '{')
	nesting_level++;
      else if (*p == '}')
Richard Stallman committed
5771
	{
5772 5773
	  if (!--nesting_level)
	    break;
Richard Stallman committed
5774
	}
5775 5776 5777 5778 5779 5780 5781
      else if (*p == ';' && nesting_level == 1)
	break;
      else if (*p == '%' && p[1] == '*' && nesting_level == 1)
	have_subst = true;
      else if (*p == '\0')
	abort ();
      p++;
Richard Stallman committed
5782
    }
5783 5784 5785 5786
  
  end_body = p;
  while (end_body[-1] == ' ' || end_body[-1] == '\t')
    end_body--;
Richard Stallman committed
5787

5788 5789
  if (have_subst && !starred)
    abort ();
5790

5791
  if (matched)
5792
    {
5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808
      /* Copy the substitution body to permanent storage and execute it.
	 If have_subst is false, this is a simple matter of running the
	 body through do_spec_1...  */
      char *string = save_string (body, end_body - body);
      if (!have_subst)
	{
	  if (do_spec_1 (string, 0, NULL) < 0)
	    return 0;
	}
      else
	{
	  /* ... but if have_subst is true, we have to process the
	     body once for each matching switch, with %* set to the
	     variant part of the switch.  */
	  unsigned int hard_match_len = end_atom - atom;
	  int i;
5809

5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821
	  for (i = 0; i < n_switches; i++)
	    if (!strncmp (switches[i].part1, atom, hard_match_len)
		&& check_live_switch (i, hard_match_len))
	      {
		if (do_spec_1 (string, 0,
			       &switches[i].part1[hard_match_len]) < 0)
		  return 0;
		/* Pass any arguments this switch has.  */
		give_switch (i, 1);
		suffix_subst = NULL;
	      }
	}
5822 5823
    }

5824
  return p;
Richard Stallman committed
5825
}
5826

5827 5828 5829
/* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
   on the command line.  PREFIX_LENGTH is the length of XXX in an {XXX*}
   spec, or -1 if either exact match or %* is used.
5830 5831 5832 5833 5834 5835

   A -O switch is obsoleted by a later -O switch.  A -f, -m, or -W switch
   whose value does not begin with "no-" is obsoleted by the same value
   with the "no-", similarly for a switch with the "no-" prefix.  */

static int
5836
check_live_switch (switchnum, prefix_length)
5837
     int switchnum;
5838
     int prefix_length;
5839
{
5840
  const char *name = switches[switchnum].part1;
5841 5842
  int i;

5843
  /* In the common case of {<at-most-one-letter>*}, a negating
5844 5845
     switch would always match, so ignore that case.  We will just
     send the conflicting switches to the compiler phase.  */
5846
  if (prefix_length >= 0 && prefix_length <= 1)
5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857
    return 1;

  /* If we already processed this switch and determined if it was
     live or not, return our past determination.  */
  if (switches[switchnum].live_cond != 0)
    return switches[switchnum].live_cond > 0;

  /* Now search for duplicate in a manner that depends on the name.  */
  switch (*name)
    {
    case 'O':
Kazu Hirata committed
5858 5859 5860 5861 5862 5863 5864
      for (i = switchnum + 1; i < n_switches; i++)
	if (switches[i].part1[0] == 'O')
	  {
	    switches[switchnum].validated = 1;
	    switches[switchnum].live_cond = SWITCH_FALSE;
	    return 0;
	  }
5865
      break;
Richard Stallman committed
5866

5867
    case 'W':  case 'f':  case 'm':
5868
      if (! strncmp (name + 1, "no-", 3))
5869
	{
Mike Stump committed
5870
	  /* We have Xno-YYY, search for XYYY.  */
5871 5872 5873
	  for (i = switchnum + 1; i < n_switches; i++)
	    if (switches[i].part1[0] == name[0]
		&& ! strcmp (&switches[i].part1[1], &name[4]))
Kazu Hirata committed
5874 5875 5876 5877 5878
	      {
		switches[switchnum].validated = 1;
		switches[switchnum].live_cond = SWITCH_FALSE;
		return 0;
	      }
5879 5880 5881 5882 5883 5884 5885 5886 5887 5888
	}
      else
	{
	  /* We have XYYY, search for Xno-YYY.  */
	  for (i = switchnum + 1; i < n_switches; i++)
	    if (switches[i].part1[0] == name[0]
		&& switches[i].part1[1] == 'n'
		&& switches[i].part1[2] == 'o'
		&& switches[i].part1[3] == '-'
		&& !strcmp (&switches[i].part1[4], &name[1]))
Kazu Hirata committed
5889 5890 5891 5892 5893
	      {
		switches[switchnum].validated = 1;
		switches[switchnum].live_cond = SWITCH_FALSE;
		return 0;
	      }
5894 5895 5896 5897 5898
	}
      break;
    }

  /* Otherwise the switch is live.  */
5899
  switches[switchnum].live_cond = SWITCH_LIVE;
5900 5901 5902
  return 1;
}

Richard Stallman committed
5903 5904 5905 5906 5907 5908
/* Pass a switch to the current accumulating command
   in the same form that we received it.
   SWITCHNUM identifies the switch; it is an index into
   the vector of switches gcc received, which is `switches'.
   This cannot fail since it never finishes a command line.

5909
   If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
Richard Stallman committed
5910 5911

static void
5912
give_switch (switchnum, omit_first_word)
Richard Stallman committed
5913 5914 5915
     int switchnum;
     int omit_first_word;
{
5916 5917 5918
  if (switches[switchnum].live_cond == SWITCH_IGNORE)
    return;

Richard Stallman committed
5919 5920
  if (!omit_first_word)
    {
5921 5922
      do_spec_1 ("-", 0, NULL);
      do_spec_1 (switches[switchnum].part1, 1, NULL);
Richard Stallman committed
5923
    }
5924

Richard Stallman committed
5925 5926
  if (switches[switchnum].args != 0)
    {
Zack Weinberg committed
5927
      const char **p;
Richard Stallman committed
5928 5929
      for (p = switches[switchnum].args; *p; p++)
	{
5930 5931
	  const char *arg = *p;

5932
	  do_spec_1 (" ", 0, NULL);
5933 5934 5935
	  if (suffix_subst)
	    {
	      unsigned length = strlen (arg);
5936
	      int dot = 0;
5937 5938 5939 5940 5941

	      while (length-- && !IS_DIR_SEPARATOR (arg[length]))
		if (arg[length] == '.')
		  {
		    ((char *)arg)[length] = 0;
5942
		    dot = 1;
5943 5944
		    break;
		  }
5945
	      do_spec_1 (arg, 1, NULL);
5946 5947 5948
	      if (dot)
		((char *)arg)[length] = '.';
	      do_spec_1 (suffix_subst, 1, NULL);
5949 5950
	    }
	  else
5951
	    do_spec_1 (arg, 1, NULL);
Richard Stallman committed
5952 5953
	}
    }
5954

5955
  do_spec_1 (" ", 0, NULL);
5956
  switches[switchnum].validated = 1;
Richard Stallman committed
5957 5958 5959 5960 5961 5962
}

/* Search for a file named NAME trying various prefixes including the
   user's -B prefix and some standard ones.
   Return the absolute file name found.  If nothing is found, return NAME.  */

5963
static const char *
Richard Stallman committed
5964
find_file (name)
5965
     const char *name;
Richard Stallman committed
5966 5967 5968
{
  char *newname;

Doug Evans committed
5969
  /* Try multilib_dir if it is defined.  */
5970
  if (multilib_os_dir != NULL)
Doug Evans committed
5971
    {
5972
      newname = find_a_file (&startfile_prefixes, name, R_OK, 1);
Doug Evans committed
5973 5974 5975 5976 5977 5978 5979

      /* If we don't find it in the multi library dir, then fall
	 through and look for it in the normal places.  */
      if (newname != NULL)
	return newname;
    }

5980
  newname = find_a_file (&startfile_prefixes, name, R_OK, 0);
Richard Stallman committed
5981 5982 5983
  return newname ? newname : name;
}

5984 5985 5986 5987
/* Determine whether a directory exists.  If LINKER, return 0 for
   certain fixed names not needed by the linker.  If not LINKER, it is
   only important to return 0 if the host machine has a small ARG_MAX
   limit.  */
Richard Stallman committed
5988 5989

static int
5990
is_directory (path1, path2, linker)
5991 5992
     const char *path1;
     const char *path2;
5993
     int linker;
Richard Stallman committed
5994 5995 5996 5997 5998 5999 6000
{
  int len1 = strlen (path1);
  int len2 = strlen (path2);
  char *path = (char *) alloca (3 + len1 + len2);
  char *cp;
  struct stat st;

6001 6002 6003 6004 6005
#ifndef SMALL_ARG_MAX
  if (! linker)
    return 1;
#endif

Richard Stallman committed
6006 6007 6008
  /* Construct the path from the two parts.  Ensure the string ends with "/.".
     The resulting path will be a directory even if the given path is a
     symbolic link.  */
6009 6010
  memcpy (path, path1, len1);
  memcpy (path + len1, path2, len2);
Richard Stallman committed
6011
  cp = path + len1 + len2;
6012
  if (!IS_DIR_SEPARATOR (cp[-1]))
6013
    *cp++ = DIR_SEPARATOR;
Richard Stallman committed
6014 6015 6016 6017
  *cp++ = '.';
  *cp = '\0';

  /* Exclude directories that the linker is known to search.  */
6018
  if (linker
6019
      && ((cp - path == 6
Kazu Hirata committed
6020
	   && strcmp (path, concat (dir_separator_str, "lib",
6021
				    dir_separator_str, ".", NULL)) == 0)
6022
	  || (cp - path == 10
Kazu Hirata committed
6023 6024
	      && strcmp (path, concat (dir_separator_str, "usr",
				       dir_separator_str, "lib",
6025
				       dir_separator_str, ".", NULL)) == 0)))
Richard Stallman committed
6026 6027 6028 6029
    return 0;

  return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
}
6030 6031 6032 6033

/* Set up the various global variables to indicate that we're processing
   the input file named FILENAME.  */

6034
void
6035 6036 6037
set_input (filename)
     const char *filename;
{
6038
  const char *p;
6039 6040 6041

  input_filename = filename;
  input_filename_length = strlen (input_filename);
Kazu Hirata committed
6042

6043
  input_basename = input_filename;
6044 6045 6046 6047 6048 6049
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  /* Skip drive name so 'x:foo' is handled properly.  */
  if (input_basename[1] == ':')
    input_basename += 2;
#endif
  for (p = input_basename; *p; p++)
6050 6051 6052 6053 6054 6055
    if (IS_DIR_SEPARATOR (*p))
      input_basename = p + 1;

  /* Find a suffix starting with the last period,
     and set basename_length to exclude that suffix.  */
  basename_length = strlen (input_basename);
6056
  suffixed_basename_length = basename_length;
6057
  p = input_basename + basename_length;
Kazu Hirata committed
6058 6059
  while (p != input_basename && *p != '.')
    --p;
6060 6061 6062 6063 6064 6065 6066
  if (*p == '.' && p != input_basename)
    {
      basename_length = p - input_basename;
      input_suffix = p + 1;
    }
  else
    input_suffix = "";
6067

6068 6069 6070 6071
  /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
     we will need to do a stat on the input_filename.  The
     INPUT_STAT_SET signals that the stat is needed.  */
  input_stat_set = 0;
6072
}
Richard Stallman committed
6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087

/* On fatal signals, delete all the temporary files.  */

static void
fatal_error (signum)
     int signum;
{
  signal (signum, SIG_DFL);
  delete_failure_queue ();
  delete_temp_files ();
  /* Get the same signal again, this time not handled,
     so its normal effect occurs.  */
  kill (getpid (), signum);
}

6088
extern int main PARAMS ((int, const char *const *));
6089

Richard Stallman committed
6090 6091 6092
int
main (argc, argv)
     int argc;
6093
     const char *const *argv;
Richard Stallman committed
6094
{
6095
  size_t i;
Richard Stallman committed
6096 6097
  int value;
  int linker_was_run = 0;
6098
  int num_linker_inputs = 0;
Richard Stallman committed
6099 6100
  char *explicit_link_files;
  char *specs_file;
6101
  const char *p;
Michael Meissner committed
6102
  struct user_specs *uptr;
Richard Stallman committed
6103

6104
  p = argv[0] + strlen (argv[0]);
6105 6106
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    --p;
6107
  programname = p;
Richard Stallman committed
6108

6109 6110
  xmalloc_set_program_name (programname);

6111
#ifdef GCC_DRIVER_HOST_INITIALIZATION
6112
  /* Perform host dependent initialization when needed.  */
6113 6114 6115
  GCC_DRIVER_HOST_INITIALIZATION;
#endif

6116
  gcc_init_libintl ();
6117

Richard Stallman committed
6118 6119
  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
    signal (SIGINT, fatal_error);
6120
#ifdef SIGHUP
Richard Stallman committed
6121 6122
  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
    signal (SIGHUP, fatal_error);
6123
#endif
Richard Stallman committed
6124 6125 6126 6127 6128 6129
  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
    signal (SIGTERM, fatal_error);
#ifdef SIGPIPE
  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
    signal (SIGPIPE, fatal_error);
#endif
6130
#ifdef SIGCHLD
Bruce Korb committed
6131 6132 6133
  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
     receive the signal.  A different setting is inheritable */
  signal (SIGCHLD, SIG_DFL);
6134
#endif
Richard Stallman committed
6135

6136 6137
  /* Allocate the argument vector.  */
  alloc_args ();
Richard Stallman committed
6138 6139 6140

  obstack_init (&obstack);

6141 6142
  /* Build multilib_select, et. al from the separate lines that make up each
     multilib selection.  */
6143
  {
Zack Weinberg committed
6144
    const char *const *q = multilib_raw;
6145
    int need_space;
6146 6147

    obstack_init (&multilib_obstack);
Mike Stump committed
6148
    while ((p = *q++) != (char *) 0)
6149 6150 6151 6152
      obstack_grow (&multilib_obstack, p, strlen (p));

    obstack_1grow (&multilib_obstack, 0);
    multilib_select = obstack_finish (&multilib_obstack);
6153 6154 6155 6156 6157 6158 6159 6160

    q = multilib_matches_raw;
    while ((p = *q++) != (char *) 0)
      obstack_grow (&multilib_obstack, p, strlen (p));

    obstack_1grow (&multilib_obstack, 0);
    multilib_matches = obstack_finish (&multilib_obstack);

6161 6162
    q = multilib_exclusions_raw;
    while ((p = *q++) != (char *) 0)
Kazu Hirata committed
6163
      obstack_grow (&multilib_obstack, p, strlen (p));
6164 6165 6166

    obstack_1grow (&multilib_obstack, 0);
    multilib_exclusions = obstack_finish (&multilib_obstack);
Kazu Hirata committed
6167

6168
    need_space = FALSE;
6169
    for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180
      {
	if (need_space)
	  obstack_1grow (&multilib_obstack, ' ');
	obstack_grow (&multilib_obstack,
		      multilib_defaults_raw[i],
		      strlen (multilib_defaults_raw[i]));
	need_space = TRUE;
      }

    obstack_1grow (&multilib_obstack, 0);
    multilib_defaults = obstack_finish (&multilib_obstack);
6181 6182
  }

6183
  /* Set up to remember the pathname of gcc and any options
6184 6185
     needed for collect.  We use argv[0] instead of programname because
     we need the complete pathname.  */
6186
  obstack_init (&collect_obstack);
Kazu Hirata committed
6187 6188
  obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
  obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
6189 6190
  putenv (obstack_finish (&collect_obstack));

6191 6192 6193 6194 6195
#ifdef INIT_ENVIRONMENT
  /* Set up any other necessary machine specific environment variables.  */
  putenv (INIT_ENVIRONMENT);
#endif

Richard Stallman committed
6196 6197 6198 6199 6200 6201 6202 6203 6204 6205
  /* Make a table of what switches there are (switches, n_switches).
     Make a table of specified input files (infiles, n_infiles).
     Decode switches that are handled locally.  */

  process_command (argc, argv);

  /* 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);
6206 6207
  memcpy ((char *) compilers, (char *) default_compilers,
	  sizeof default_compilers);
Richard Stallman committed
6208 6209 6210 6211
  n_compilers = n_default_compilers;

  /* Read specs from a file if there is one.  */

6212
  machine_suffix = concat (spec_machine, dir_separator_str,
6213 6214
			   spec_version, dir_separator_str, NULL);
  just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
Richard Stallman committed
6215

6216
  specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0);
Richard Stallman committed
6217 6218
  /* Read the specs file unless it is a default one.  */
  if (specs_file != 0 && strcmp (specs_file, "specs"))
6219 6220 6221
    read_specs (specs_file, TRUE);
  else
    init_spec ();
Michael Meissner committed
6222

6223
  /* We need to check standard_exec_prefix/just_machine_suffix/specs
6224
     for any override of as, ld and libraries.  */
6225 6226 6227 6228 6229 6230 6231 6232 6233
  specs_file = (char *) alloca (strlen (standard_exec_prefix)
				+ strlen (just_machine_suffix)
				+ sizeof ("specs"));

  strcpy (specs_file, standard_exec_prefix);
  strcat (specs_file, just_machine_suffix);
  strcat (specs_file, "specs");
  if (access (specs_file, R_OK) == 0)
    read_specs (specs_file, TRUE);
Kazu Hirata committed
6234

6235 6236 6237 6238 6239 6240
  /* Process DRIVER_SELF_SPECS, adding any new options to the end
     of the command line.  */

  for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
    do_self_spec (driver_self_specs[i]);

6241 6242 6243
  /* If not cross-compiling, look for executables in the standard
     places.  */
  if (*cross_compile == '0')
6244
    {
6245 6246 6247
      if (*md_exec_prefix)
	{
	  add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
6248
		      PREFIX_PRIORITY_LAST, 0, NULL, 0);
6249
	}
6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268
    }

  /* Look for startfiles in the standard places.  */
  if (*startfile_prefix_spec != 0
      && do_spec_2 (startfile_prefix_spec) == 0
      && do_spec_1 (" ", 0, NULL) == 0)
    {
      int ndx;
      for (ndx = 0; ndx < argbuf_index; ndx++)
	add_sysrooted_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
			      PREFIX_PRIORITY_LAST, 0, NULL, 1);
    }
  /* We should eventually get rid of all these and stick to
     startfile_prefix_spec exclusively.  */
  else if (*cross_compile == '0' || target_system_root)
    {
      if (*md_exec_prefix)
	add_sysrooted_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
			      PREFIX_PRIORITY_LAST, 0, NULL, 1);
6269

6270
      if (*md_startfile_prefix)
6271 6272
	add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
			      "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
6273

6274
      if (*md_startfile_prefix_1)
6275 6276
	add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
			      "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
6277

6278 6279 6280 6281
      /* 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.  */
6282
      if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix))
6283 6284 6285
	add_sysrooted_prefix (&startfile_prefixes,
			      standard_startfile_prefix, "BINUTILS",
			      PREFIX_PRIORITY_LAST, 0, NULL, 1);
6286 6287 6288
      else
	{
	  if (gcc_exec_prefix)
6289
	    add_prefix (&startfile_prefixes,
6290
			concat (gcc_exec_prefix, machine_suffix,
6291
				standard_startfile_prefix, NULL),
6292
			NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
6293
	  add_prefix (&startfile_prefixes,
6294 6295
		      concat (standard_exec_prefix,
			      machine_suffix,
6296
			      standard_startfile_prefix, NULL),
6297
		      NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
Kazu Hirata committed
6298
	}
6299

6300 6301 6302 6303
      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);
6304
#if 0 /* Can cause surprises, and one can use -B./ instead.  */
6305
      add_prefix (&startfile_prefixes, "./", NULL,
6306
		  PREFIX_PRIORITY_LAST, 1, NULL, 0);
6307 6308
#endif
    }
6309

6310 6311 6312 6313
  /* Process any user specified specs in the order given on the command
     line.  */
  for (uptr = user_specs_head; uptr; uptr = uptr->next)
    {
6314 6315
      char *filename = find_a_file (&startfile_prefixes, uptr->filename,
				    R_OK, 0);
6316 6317 6318
      read_specs (filename ? filename : uptr->filename, FALSE);
    }

6319 6320
  /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
  if (gcc_exec_prefix)
6321 6322
    gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
			      spec_version, dir_separator_str, NULL);
6323

Richard Stallman committed
6324 6325 6326 6327 6328
  /* Now we have the specs.
     Set the `valid' bits for switches that match anything in any spec.  */

  validate_all_switches ();

Doug Evans committed
6329 6330 6331 6332
  /* Now that we have the switches and the specs, set
     the subdirectory based on the options.  */
  set_multilib_dir ();

Richard Stallman committed
6333 6334
  /* Warn about any switches that no pass was interested in.  */

Kazu Hirata committed
6335
  for (i = 0; (int) i < n_switches; i++)
6336
    if (! switches[i].validated)
Richard Stallman committed
6337 6338
      error ("unrecognized option `-%s'", switches[i].part1);

6339 6340
  /* Obey some of the options.  */

6341 6342
  if (print_search_dirs)
    {
6343 6344 6345
      printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
      printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
      printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
6346
      return (0);
6347 6348
    }

6349
  if (print_file_name)
6350
    {
6351
      printf ("%s\n", find_file (print_file_name));
6352
      return (0);
6353 6354
    }

6355 6356
  if (print_prog_name)
    {
6357
      char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
6358
      printf ("%s\n", (newname ? newname : print_prog_name));
6359
      return (0);
6360
    }
Richard Stallman committed
6361

Doug Evans committed
6362 6363 6364
  if (print_multi_lib)
    {
      print_multilib_info ();
6365
      return (0);
Doug Evans committed
6366 6367 6368 6369 6370 6371 6372 6373
    }

  if (print_multi_directory)
    {
      if (multilib_dir == NULL)
	printf (".\n");
      else
	printf ("%s\n", multilib_dir);
6374
      return (0);
Doug Evans committed
6375 6376
    }

6377 6378 6379 6380 6381 6382 6383 6384 6385
  if (print_multi_os_directory)
    {
      if (multilib_os_dir == NULL)
	printf (".\n");
      else
	printf ("%s\n", multilib_os_dir);
      return (0);
    }

6386 6387
  if (target_help_flag)
   {
6388
      /* Print if any target specific options.  */
6389 6390 6391 6392

      /* We do not exit here. Instead we have created a fake input file
         called 'target-dummy' which needs to be compiled, and we pass this
         on to the various sub-processes, along with the --target-help
6393
         switch.  */
6394 6395
    }

Nick Clifton committed
6396 6397 6398 6399 6400 6401
  if (print_help_list)
    {
      display_help ();

      if (! verbose_flag)
	{
6402
	  printf (_("\nFor bug reporting instructions, please see:\n"));
6403
	  printf ("%s.\n", bug_report_url);
Kazu Hirata committed
6404

6405
	  return (0);
Nick Clifton committed
6406 6407 6408 6409
	}

      /* We do not exit here.  Instead we have created a fake input file
	 called 'help-dummy' which needs to be compiled, and we pass this
6410
	 on the various sub-processes, along with the --help switch.  */
Nick Clifton committed
6411
    }
Kazu Hirata committed
6412

Richard Stallman committed
6413 6414
  if (verbose_flag)
    {
6415
      int n;
6416
      const char *thrmod;
6417

6418 6419
      notice ("Configured with: %s\n", configuration_arguments);

6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432
#ifdef THREAD_MODEL_SPEC
      /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
	 but there's no point in doing all this processing just to get
	 thread_model back.  */
      obstack_init (&obstack);
      do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
      obstack_1grow (&obstack, '\0');
      thrmod = obstack_finish (&obstack);
#else
      thrmod = thread_model;
#endif

      notice ("Thread model: %s\n", thrmod);
6433

6434 6435 6436 6437 6438 6439 6440 6441 6442
      /* compiler_version is truncated at the first space when initialized
	 from version string, so truncate version_string at the first space
	 before comparing.  */
      for (n = 0; version_string[n]; n++)
	if (version_string[n] == ' ')
	  break;

      if (! strncmp (version_string, compiler_version, n)
	  && compiler_version[n] == 0)
6443
	notice ("gcc version %s\n", version_string);
6444
      else
6445 6446
	notice ("gcc driver version %s executing gcc version %s\n",
		version_string, compiler_version);
6447

Richard Stallman committed
6448
      if (n_infiles == 0)
6449
	return (0);
Richard Stallman committed
6450 6451
    }

6452
  if (n_infiles == added_libraries)
6453
    fatal ("no input files");
Richard Stallman committed
6454 6455 6456 6457

  /* Make a place to record the compiler output file names
     that correspond to the input files.  */

6458
  i = n_infiles;
Per Bothner committed
6459
  i += lang_specific_extra_outfiles;
6460
  outfiles = (const char **) xcalloc (i, sizeof (char *));
Richard Stallman committed
6461 6462 6463

  /* Record which files were specified explicitly as link input.  */

6464
  explicit_link_files = xcalloc (1, n_infiles);
Richard Stallman committed
6465

Kazu Hirata committed
6466
  for (i = 0; (int) i < n_infiles; i++)
Richard Stallman committed
6467 6468 6469 6470 6471 6472
    {
      int this_file_error = 0;

      /* Tell do_spec what to substitute for %i.  */

      input_file_number = i;
6473
      set_input (infiles[i].name);
Richard Stallman committed
6474 6475 6476 6477 6478 6479 6480

      /* Use the same thing in %o, unless cp->spec says otherwise.  */

      outfiles[i] = input_filename;

      /* Figure out which compiler from the file's suffix.  */

6481 6482 6483
      input_file_compiler
	= lookup_compiler (infiles[i].name, input_filename_length,
			   infiles[i].language);
6484

6485
      if (input_file_compiler)
Richard Stallman committed
6486 6487 6488
	{
	  /* Ok, we found an applicable compiler.  Run its spec.  */

6489
	  if (input_file_compiler->spec[0] == '#')
6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500
	    {
	      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);
	      if (value < 0)
		this_file_error = 1;
	    }
Richard Stallman committed
6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520
	}

      /* If this file's name does not contain a recognized suffix,
	 record it as explicit linker input.  */

      else
	explicit_link_files[i] = 1;

      /* Clear the delete-on-failure queue, deleting the files in it
	 if this compilation failed.  */

      if (this_file_error)
	{
	  delete_failure_queue ();
	  error_count++;
	}
      /* If this compilation succeeded, don't delete those files later.  */
      clear_failure_queue ();
    }

6521 6522 6523 6524 6525 6526
  /* Reset the output file name to the first input file name, for use
     with %b in LINK_SPEC on a target that prefers not to emit a.out
     by default.  */
  if (n_infiles > 0)
    set_input (infiles[0].name);

6527 6528 6529 6530 6531 6532 6533 6534
  if (error_count == 0)
    {
      /* Make sure INPUT_FILE_NUMBER points to first available open
	 slot.  */
      input_file_number = n_infiles;
      if (lang_specific_pre_link ())
	error_count++;
    }
6535

6536 6537 6538 6539 6540 6541
  /* Determine if there are any linker input files.  */
  num_linker_inputs = 0;
  for (i = 0; (int) i < n_infiles; i++)
    if (explicit_link_files[i] || outfiles[i] != NULL)
      num_linker_inputs++;

Richard Stallman committed
6542 6543
  /* Run ld to link all the compiler output files.  */

6544
  if (num_linker_inputs > 0 && error_count == 0)
Richard Stallman committed
6545 6546
    {
      int tmp = execution_count;
6547

Kazu Hirata committed
6548
      /* We'll use ld if we can't find collect2.  */
Bob Manson committed
6549 6550
      if (! strcmp (linker_name_spec, "collect2"))
	{
6551
	  char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0);
Bob Manson committed
6552 6553 6554
	  if (s == NULL)
	    linker_name_spec = "ld";
	}
6555 6556
      /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
	 for collect.  */
6557 6558
      putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH");
      putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV);
6559

Richard Stallman committed
6560 6561 6562 6563 6564 6565 6566 6567 6568
      value = do_spec (link_command_spec);
      if (value < 0)
	error_count = 1;
      linker_was_run = (tmp != execution_count);
    }

  /* If options said don't run linker,
     complain about input files to be given to the linker.  */

6569
  if (! linker_was_run && error_count == 0)
Kazu Hirata committed
6570
    for (i = 0; (int) i < n_infiles; i++)
Richard Stallman committed
6571
      if (explicit_link_files[i])
6572
	error ("%s: linker input file unused because linking not done",
Richard Stallman committed
6573 6574 6575 6576 6577 6578 6579 6580
	       outfiles[i]);

  /* Delete some or all of the temporary files we made.  */

  if (error_count)
    delete_failure_queue ();
  delete_temp_files ();

Nick Clifton committed
6581 6582
  if (print_help_list)
    {
6583
      printf (("\nFor bug reporting instructions, please see:\n"));
6584
      printf ("%s\n", bug_report_url);
Nick Clifton committed
6585
    }
Kazu Hirata committed
6586

Richard Kenner committed
6587 6588 6589
  return (signal_count != 0 ? 2
	  : error_count > 0 ? (pass_exit_codes ? greatest_status : 1)
	  : 0);
Richard Stallman committed
6590 6591 6592
}

/* Find the proper compilation spec for the file name NAME,
6593
   whose length is LENGTH.  LANGUAGE is the specified language,
6594
   or 0 if this file is to be passed to the linker.  */
Richard Stallman committed
6595 6596 6597

static struct compiler *
lookup_compiler (name, length, language)
6598
     const char *name;
6599
     size_t length;
6600
     const char *language;
Richard Stallman committed
6601 6602 6603
{
  struct compiler *cp;

6604
  /* If this was specified by the user to be a linker input, indicate that.  */
6605 6606 6607 6608
  if (language != 0 && language[0] == '*')
    return 0;

  /* Otherwise, look for the language, if one is spec'd.  */
Richard Stallman committed
6609 6610 6611
  if (language != 0)
    {
      for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
6612 6613 6614
	if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
	  return cp;

Richard Stallman committed
6615
      error ("language %s not recognized", language);
6616
      return 0;
Richard Stallman committed
6617 6618 6619 6620 6621
    }

  /* Look for a suffix.  */
  for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    {
6622 6623
      if (/* The suffix `-' matches only the file name `-'.  */
	  (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
6624 6625 6626 6627 6628
	  || (strlen (cp->suffix) < length
	      /* See if the suffix matches the end of NAME.  */
	      && !strcmp (cp->suffix,
			  name + length - strlen (cp->suffix))
	 ))
6629
	break;
6630
    }
6631

6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652
#if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
  /* look again, but case-insensitively this time.  */
  if (cp < compilers)
    for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
      {
	if (/* The suffix `-' matches only the file name `-'.  */
	    (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
	    || (strlen (cp->suffix) < length
		/* See if the suffix matches the end of NAME.  */
		&& ((!strcmp (cp->suffix,
			     name + length - strlen (cp->suffix))
		     || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
		    && !strcasecmp (cp->suffix,
				    name + length - strlen (cp->suffix)))
	   ))
	  break;
      }
#endif

  if (cp >= compilers)
    {
6653 6654 6655
      if (cp->spec[0] != '@')
	/* A non-alias entry: return it.  */
	return cp;
Kazu Hirata committed
6656

6657 6658 6659
      /* An alias entry maps a suffix to a language.
	 Search for the language; pass 0 for NAME and LENGTH
	 to avoid infinite recursion if language not found.  */
6660
      return lookup_compiler (NULL, 0, cp->spec + 1);
Richard Stallman committed
6661 6662 6663 6664
    }
  return 0;
}

6665
static char *
Richard Stallman committed
6666
save_string (s, len)
Kazu Hirata committed
6667 6668
     const char *s;
     int len;
Richard Stallman committed
6669
{
6670
  char *result = xmalloc (len + 1);
Richard Stallman committed
6671

6672
  memcpy (result, s, len);
Richard Stallman committed
6673 6674 6675 6676
  result[len] = 0;
  return result;
}

6677
void
Richard Stallman committed
6678
pfatal_with_name (name)
6679
     const char *name;
Richard Stallman committed
6680
{
6681 6682 6683
  perror_with_name (name);
  delete_temp_files ();
  exit (1);
Richard Stallman committed
6684 6685 6686 6687
}

static void
perror_with_name (name)
6688
     const char *name;
Richard Stallman committed
6689
{
6690
  error ("%s: %s", name, xstrerror (errno));
Richard Stallman committed
6691 6692 6693
}

static void
6694
pfatal_pexecute (errmsg_fmt, errmsg_arg)
6695 6696
     const char *errmsg_fmt;
     const char *errmsg_arg;
Richard Stallman committed
6697
{
6698 6699
  if (errmsg_arg)
    {
6700 6701
      int save_errno = errno;

6702 6703 6704 6705
      /* Space for trailing '\0' is in %s.  */
      char *msg = xmalloc (strlen (errmsg_fmt) + strlen (errmsg_arg));
      sprintf (msg, errmsg_fmt, errmsg_arg);
      errmsg_fmt = msg;
6706 6707

      errno = save_errno;
6708 6709
    }

6710
  pfatal_with_name (errmsg_fmt);
Richard Stallman committed
6711 6712
}

6713
/* Output an error message and exit */
Richard Stallman committed
6714 6715 6716 6717

void
fancy_abort ()
{
6718
  fatal ("internal gcc abort");
Richard Stallman committed
6719 6720 6721 6722
}

/* Output an error message and exit */

6723
void
6724
fatal VPARAMS ((const char *msgid, ...))
Richard Stallman committed
6725
{
6726 6727
  VA_OPEN (ap, msgid);
  VA_FIXEDARG (ap, const char *, msgid);
Richard Stallman committed
6728 6729

  fprintf (stderr, "%s: ", programname);
6730
  vfprintf (stderr, _(msgid), ap);
6731
  VA_CLOSE (ap);
Richard Stallman committed
6732 6733 6734 6735 6736
  fprintf (stderr, "\n");
  delete_temp_files ();
  exit (1);
}

6737
void
6738
error VPARAMS ((const char *msgid, ...))
Richard Stallman committed
6739
{
6740 6741
  VA_OPEN (ap, msgid);
  VA_FIXEDARG (ap, const char *, msgid);
Richard Stallman committed
6742 6743

  fprintf (stderr, "%s: ", programname);
6744
  vfprintf (stderr, _(msgid), ap);
6745
  VA_CLOSE (ap);
Richard Stallman committed
6746 6747 6748

  fprintf (stderr, "\n");
}
6749 6750

static void
6751
notice VPARAMS ((const char *msgid, ...))
6752
{
6753 6754
  VA_OPEN (ap, msgid);
  VA_FIXEDARG (ap, const char *, msgid);
6755 6756

  vfprintf (stderr, _(msgid), ap);
6757
  VA_CLOSE (ap);
6758
}
Richard Stallman committed
6759

6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771
static inline void
validate_switches_from_spec (spec)
     const char *spec;
{
  const char *p = spec;
  char c;
  while ((c = *p++))
    if (c == '%' && (*p == '{' || *p == '<' || (*p == 'W' && *++p == '{')))
      /* We have a switch spec.  */
      p = validate_switches (p + 1);
}

Richard Stallman committed
6772 6773 6774 6775
static void
validate_all_switches ()
{
  struct compiler *comp;
6776
  struct spec_list *spec;
Richard Stallman committed
6777

6778
  for (comp = compilers; comp->spec; comp++)
6779
    validate_switches_from_spec (comp->spec);
Richard Stallman committed
6780

6781
  /* Look through the linked list of specs read from the specs file.  */
Kazu Hirata committed
6782
  for (spec = specs; spec; spec = spec->next)
6783
    validate_switches_from_spec (*spec->ptr_spec);
6784

6785
  validate_switches_from_spec (link_command_spec);
Richard Stallman committed
6786 6787 6788 6789 6790
}

/* Look at the switch-name that comes after START
   and mark as valid all supplied switches that match it.  */

6791
static const char *
Richard Stallman committed
6792
validate_switches (start)
6793
     const char *start;
Richard Stallman committed
6794
{
6795
  const char *p = start;
6796 6797
  const char *atom;
  size_t len;
6798
  int i;
6799 6800 6801 6802 6803
  bool suffix = false;
  bool starred = false;
  
#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
  
6804
next_member:
6805 6806
  SKIP_WHITE ();

Richard Stallman committed
6807
  if (*p == '!')
6808
    p++;
Richard Stallman committed
6809

6810
  SKIP_WHITE ();
Richard Stallman committed
6811
  if (*p == '.')
6812
    suffix = true, p++;
Richard Stallman committed
6813

6814 6815
  atom = p;
  while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
6816
	 || *p == ',' || *p == '.' || *p == '@')
Kazu Hirata committed
6817
    p++;
6818
  len = p - atom;
Richard Stallman committed
6819

6820 6821 6822 6823 6824 6825
  if (*p == '*')
    starred = true, p++;

  SKIP_WHITE ();

  if (!suffix)
Richard Stallman committed
6826 6827 6828
    {
      /* Mark all matching switches as valid.  */
      for (i = 0; i < n_switches; i++)
6829 6830
	if (!strncmp (switches[i].part1, atom, len)
	    && (starred || switches[i].part1[len] == 0))
6831
	  switches[i].validated = 1;
Richard Stallman committed
6832
    }
6833

6834 6835
  if (*p) p++;
  if (*p && (p[-1] == '|' || p[-1] == '&'))
6836 6837
    goto next_member;

6838
  if (*p && p[-1] == ':')
Richard Stallman committed
6839
    {
6840
      while (*p && *p != ';' && *p != '}')
Richard Stallman committed
6841
	{
6842 6843 6844 6845 6846 6847 6848 6849
	  if (*p == '%')
	    {
	      p++;
	      if (*p == '{' || *p == '<')
		p = validate_switches (p+1);
	      else if (p[0] == 'W' && p[1] == '{')
		p = validate_switches (p+2);
	    }
6850
	  if (*p) p++;
Richard Stallman committed
6851
	}
6852

6853 6854
      if (*p) p++;
      if (*p && p[-1] == ';')
6855
	goto next_member;
Richard Stallman committed
6856
    }
6857

6858 6859
  return p;
#undef SKIP_WHITE
Richard Stallman committed
6860
}
Doug Evans committed
6861

6862 6863 6864 6865 6866 6867 6868 6869 6870
struct mdswitchstr
{
  const char *str;
  int len;
};

static struct mdswitchstr *mdswitches;
static int n_mdswitches;

6871
/* Check whether a particular argument was used.  The first time we
Jeff Law committed
6872
   canonicalize the switches to keep only the ones we care about.  */
Doug Evans committed
6873 6874 6875

static int
used_arg (p, len)
6876
     const char *p;
Doug Evans committed
6877 6878
     int len;
{
6879 6880
  struct mswitchstr
  {
Zack Weinberg committed
6881 6882
    const char *str;
    const char *replace;
6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893
    int len;
    int rep_len;
  };

  static struct mswitchstr *mswitches;
  static int n_mswitches;
  int i, j;

  if (!mswitches)
    {
      struct mswitchstr *matches;
Zack Weinberg committed
6894
      const char *q;
Michael Meissner committed
6895
      int cnt = 0;
6896

Kazu Hirata committed
6897 6898
      /* Break multilib_matches into the component strings of string
         and replacement string.  */
6899 6900
      for (q = multilib_matches; *q != '\0'; q++)
	if (*q == ';')
6901 6902
	  cnt++;

Kazu Hirata committed
6903 6904
      matches =
	(struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916
      i = 0;
      q = multilib_matches;
      while (*q != '\0')
	{
	  matches[i].str = q;
	  while (*q != ' ')
	    {
	      if (*q == '\0')
		abort ();
	      q++;
	    }
	  matches[i].len = q - matches[i].str;
Doug Evans committed
6917

6918 6919 6920 6921 6922 6923 6924 6925 6926
	  matches[i].replace = ++q;
	  while (*q != ';' && *q != '\0')
	    {
	      if (*q == ' ')
		abort ();
	      q++;
	    }
	  matches[i].rep_len = q - matches[i].replace;
	  i++;
6927 6928
	  if (*q == ';')
	    q++;
6929
	}
Doug Evans committed
6930

6931 6932 6933 6934 6935
      /* Now build a list of the replacement string for switches that we care
	 about.  Make sure we allocate at least one entry.  This prevents
	 xmalloc from calling fatal, and prevents us from re-executing this
	 block of code.  */
      mswitches
6936 6937 6938
	= (struct mswitchstr *)
	  xmalloc (sizeof (struct mswitchstr)
		   * (n_mdswitches + (n_switches ? n_switches : 1)));
6939 6940 6941 6942
      for (i = 0; i < n_switches; i++)
	{
	  int xlen = strlen (switches[i].part1);
	  for (j = 0; j < cnt; j++)
Zack Weinberg committed
6943 6944
	    if (xlen == matches[j].len
		&& ! strncmp (switches[i].part1, matches[j].str, xlen))
6945 6946 6947
	      {
		mswitches[n_mswitches].str = matches[j].replace;
		mswitches[n_mswitches].len = matches[j].rep_len;
Kazu Hirata committed
6948
		mswitches[n_mswitches].replace = (char *) 0;
6949 6950 6951 6952 6953
		mswitches[n_mswitches].rep_len = 0;
		n_mswitches++;
		break;
	      }
	}
6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004

      /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
	 on the command line nor any options mutually incompatible with
	 them.  */
      for (i = 0; i < n_mdswitches; i++)
	{
	  const char *r;

	  for (q = multilib_options; *q != '\0'; q++)
	    {
	      while (*q == ' ')
		q++;

	      r = q;
	      while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
		     || strchr (" /", q[mdswitches[i].len]) == NULL)
		{
		  while (*q != ' ' && *q != '/' && *q != '\0')
		    q++;
		  if (*q != '/')
		    break;
		  q++;
		}

	      if (*q != ' ' && *q != '\0')
		{
		  while (*r != ' ' && *r != '\0')
		    {
		      q = r;
		      while (*q != ' ' && *q != '/' && *q != '\0')
			q++;

		      if (used_arg (r, q - r))
			break;

		      if (*q != '/')
			{
			  mswitches[n_mswitches].str = mdswitches[i].str;
			  mswitches[n_mswitches].len = mdswitches[i].len;
			  mswitches[n_mswitches].replace = (char *) 0;
			  mswitches[n_mswitches].rep_len = 0;
			  n_mswitches++;
			  break;
			}

		      r = q + 1;
		    }
		  break;
		}
	    }
	}
7005
    }
7006

7007 7008 7009
  for (i = 0; i < n_mswitches; i++)
    if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
      return 1;
7010

7011 7012
  return 0;
}
7013 7014 7015

static int
default_arg (p, len)
7016
     const char *p;
7017 7018
     int len;
{
7019
  int i;
7020

7021 7022 7023
  for (i = 0; i < n_mdswitches; i++)
    if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
      return 1;
7024 7025 7026 7027

  return 0;
}

7028 7029 7030 7031 7032 7033 7034 7035 7036 7037
/* Work out the subdirectory to use based on the options. The format of
   multilib_select is a list of elements. Each element is a subdirectory
   name followed by a list of options followed by a semicolon. The format
   of multilib_exclusions is the same, but without the preceding
   directory. First gcc will check the exclusions, if none of the options
   beginning with an exclamation point are present, and all of the other
   options are present, then we will ignore this completely. Passing
   that, gcc will consider each multilib_select in turn using the same
   rules for matching the options. If a match is found, that subdirectory
   will be used.  */
Doug Evans committed
7038 7039 7040 7041

static void
set_multilib_dir ()
{
Zack Weinberg committed
7042
  const char *p;
7043
  unsigned int this_path_len;
Zack Weinberg committed
7044
  const char *this_path, *this_arg;
7045
  const char *start, *end;
7046
  int not_arg;
7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089
  int ok, ndfltok, first;

  n_mdswitches = 0;
  start = multilib_defaults;
  while (*start == ' ' || *start == '\t')
    start++;
  while (*start != '\0')
    {
      n_mdswitches++;
      while (*start != ' ' && *start != '\t' && *start != '\0')
	start++;
      while (*start == ' ' || *start == '\t')
        start++;
    }

  if (n_mdswitches)
    {
      int i = 0;

      mdswitches
        = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr)
					  * n_mdswitches);
      for (start = multilib_defaults; *start != '\0'; start = end + 1)
	{
	  while (*start == ' ' || *start == '\t')
	    start++;

	  if (*start == '\0')
	    break;
                                  
	  for (end = start + 1;
	       *end != ' ' && *end != '\t' && *end != '\0'; end++)
	    ;

	  obstack_grow (&multilib_obstack, start, end - start);
	  obstack_1grow (&multilib_obstack, 0);
	  mdswitches[i].str = obstack_finish (&multilib_obstack);
	  mdswitches[i++].len = end - start;

	  if (*end == '\0')
	    break;
	}
    }
Doug Evans committed
7090

7091 7092 7093 7094 7095
  p = multilib_exclusions;
  while (*p != '\0')
    {
      /* Ignore newlines.  */
      if (*p == '\n')
Kazu Hirata committed
7096 7097 7098 7099
	{
	  ++p;
	  continue;
	}
7100 7101 7102 7103

      /* Check the arguments.  */
      ok = 1;
      while (*p != ';')
Kazu Hirata committed
7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128
	{
	  if (*p == '\0')
	    abort ();

	  if (! ok)
	    {
	      ++p;
	      continue;
	    }

	  this_arg = p;
	  while (*p != ' ' && *p != ';')
	    {
	      if (*p == '\0')
		abort ();
	      ++p;
	    }

	  if (*this_arg != '!')
	    not_arg = 0;
	  else
	    {
	      not_arg = 1;
	      ++this_arg;
	    }
Kazu Hirata committed
7129

7130 7131 7132 7133
	  ok = used_arg (this_arg, p - this_arg);
	  if (not_arg)
	    ok = ! ok;

Kazu Hirata committed
7134 7135 7136
	  if (*p == ' ')
	    ++p;
	}
7137 7138

      if (ok)
7139
	return;
7140 7141 7142 7143

      ++p;
    }

7144
  first = 1;
7145
  p = multilib_select;
Doug Evans committed
7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165
  while (*p != '\0')
    {
      /* Ignore newlines.  */
      if (*p == '\n')
	{
	  ++p;
	  continue;
	}

      /* Get the initial path.  */
      this_path = p;
      while (*p != ' ')
	{
	  if (*p == '\0')
	    abort ();
	  ++p;
	}
      this_path_len = p - this_path;

      /* Check the arguments.  */
7166
      ok = 1;
7167
      ndfltok = 1;
Doug Evans committed
7168 7169 7170 7171 7172 7173
      ++p;
      while (*p != ';')
	{
	  if (*p == '\0')
	    abort ();

7174
	  if (! ok)
Doug Evans committed
7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187
	    {
	      ++p;
	      continue;
	    }

	  this_arg = p;
	  while (*p != ' ' && *p != ';')
	    {
	      if (*p == '\0')
		abort ();
	      ++p;
	    }

7188 7189
	  if (*this_arg != '!')
	    not_arg = 0;
Doug Evans committed
7190
	  else
7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202
	    {
	      not_arg = 1;
	      ++this_arg;
	    }

	  /* If this is a default argument, we can just ignore it.
	     This is true even if this_arg begins with '!'.  Beginning
	     with '!' does not mean that this argument is necessarily
	     inappropriate for this library: it merely means that
	     there is a more specific library which uses this
	     argument.  If this argument is a default, we need not
	     consider that more specific library.  */
7203 7204 7205 7206 7207 7208 7209 7210 7211
	  ok = used_arg (this_arg, p - this_arg);
	  if (not_arg)
	    ok = ! ok;

	  if (! ok)
	    ndfltok = 0;

	  if (default_arg (this_arg, p - this_arg))
	    ok = 1;
Doug Evans committed
7212 7213 7214 7215 7216

	  if (*p == ' ')
	    ++p;
	}

7217
      if (ok && first)
Doug Evans committed
7218 7219 7220 7221
	{
	  if (this_path_len != 1
	      || this_path[0] != '.')
	    {
Kazu Hirata committed
7222
	      char *new_multilib_dir = xmalloc (this_path_len + 1);
7223 7224
	      char *q;

7225 7226
	      strncpy (new_multilib_dir, this_path, this_path_len);
	      new_multilib_dir[this_path_len] = '\0';
7227 7228 7229
	      q = strchr (new_multilib_dir, ':');
	      if (q != NULL)
		*q = '\0';
7230
	      multilib_dir = new_multilib_dir;
Doug Evans committed
7231
	    }
7232 7233 7234 7235 7236 7237 7238 7239 7240
	  first = 0;
	}

      if (ndfltok)
	{
	  const char *q = this_path, *end = this_path + this_path_len;

	  while (q < end && *q != ':')
	    q++;
7241
	  if (q < end)
7242 7243
	    {
	      char *new_multilib_os_dir = xmalloc (end - q);
7244 7245
	      memcpy (new_multilib_os_dir, q + 1, end - q - 1);
	      new_multilib_os_dir[end - q - 1] = '\0';
7246 7247 7248
	      multilib_os_dir = new_multilib_os_dir;
	      break;
	    }
Doug Evans committed
7249 7250 7251
	}

      ++p;
Kazu Hirata committed
7252
    }
7253 7254 7255 7256 7257 7258 7259 7260 7261

  if (multilib_dir == NULL && multilib_os_dir != NULL
      && strcmp (multilib_os_dir, ".") == 0)
    {
      free ((char *) multilib_os_dir);
      multilib_os_dir = NULL;
    }
  else if (multilib_dir != NULL && multilib_os_dir == NULL)
    multilib_os_dir = multilib_dir;
Doug Evans committed
7262 7263 7264 7265 7266 7267 7268 7269 7270
}

/* Print out the multiple library subdirectory selection
   information.  This prints out a series of lines.  Each line looks
   like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
   required.  Only the desired options are printed out, the negative
   matches.  The options are print without a leading dash.  There are
   no spaces to make it easy to use the information in the shell.
   Each subdirectory is printed only once.  This assumes the ordering
7271 7272
   generated by the genmultilib script. Also, we leave out ones that match
   the exclusions.  */
Doug Evans committed
7273 7274 7275 7276

static void
print_multilib_info ()
{
Zack Weinberg committed
7277 7278
  const char *p = multilib_select;
  const char *last_path = 0, *this_path;
7279
  int skip;
7280
  unsigned int last_path_len = 0;
Doug Evans committed
7281 7282 7283

  while (*p != '\0')
    {
7284
      skip = 0;
Doug Evans committed
7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300
      /* Ignore newlines.  */
      if (*p == '\n')
	{
	  ++p;
	  continue;
	}

      /* Get the initial path.  */
      this_path = p;
      while (*p != ' ')
	{
	  if (*p == '\0')
	    abort ();
	  ++p;
	}

7301 7302 7303 7304 7305 7306
      /* When --disable-multilib was used but target defines
	 MULTILIB_OSDIRNAMES, entries starting with .: are there just
	 to find multilib_os_dir, so skip them from output.  */
      if (this_path[0] == '.' && this_path[1] == ':')
	skip = 1;

7307 7308 7309
      /* Check for matches with the multilib_exclusions. We don't bother
         with the '!' in either list. If any of the exclusion rules match
         all of its options with the select rule, we skip it.  */
Kazu Hirata committed
7310 7311 7312
      {
	const char *e = multilib_exclusions;
	const char *this_arg;
7313

Kazu Hirata committed
7314 7315 7316 7317 7318 7319 7320 7321 7322
	while (*e != '\0')
	  {
	    int m = 1;
	    /* Ignore newlines.  */
	    if (*e == '\n')
	      {
		++e;
		continue;
	      }
7323

Kazu Hirata committed
7324 7325 7326 7327 7328
	    /* Check the arguments.  */
	    while (*e != ';')
	      {
		const char *q;
		int mp = 0;
7329

Kazu Hirata committed
7330 7331
		if (*e == '\0')
		  abort ();
Kazu Hirata committed
7332

Kazu Hirata committed
7333 7334 7335 7336 7337
		if (! m)
		  {
		    ++e;
		    continue;
		  }
7338

Kazu Hirata committed
7339
		this_arg = e;
Kazu Hirata committed
7340

Kazu Hirata committed
7341 7342 7343 7344 7345 7346
		while (*e != ' ' && *e != ';')
		  {
		    if (*e == '\0')
		      abort ();
		    ++e;
		  }
7347

Kazu Hirata committed
7348 7349 7350 7351 7352
		q = p + 1;
		while (*q != ';')
		  {
		    const char *arg;
		    int len = e - this_arg;
7353

Kazu Hirata committed
7354 7355
		    if (*q == '\0')
		      abort ();
7356

Kazu Hirata committed
7357 7358 7359 7360 7361 7362
		    arg = q;

		    while (*q != ' ' && *q != ';')
		      {
			if (*q == '\0')
			  abort ();
7363
			++q;
Kazu Hirata committed
7364
		      }
7365

Kazu Hirata committed
7366 7367 7368 7369 7370 7371
		    if (! strncmp (arg, this_arg, (len < q - arg) ? q - arg : len) ||
			default_arg (this_arg, e - this_arg))
		      {
			mp = 1;
			break;
		      }
7372

Kazu Hirata committed
7373 7374 7375
		    if (*q == ' ')
		      ++q;
		  }
Kazu Hirata committed
7376

Kazu Hirata committed
7377 7378
		if (! mp)
		  m = 0;
7379

Kazu Hirata committed
7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393
		if (*e == ' ')
		  ++e;
	      }

	    if (m)
	      {
		skip = 1;
		break;
	      }

	    if (*e != '\0')
	      ++e;
	  }
      }
7394 7395

      if (! skip)
Kazu Hirata committed
7396 7397 7398 7399
	{
	  /* If this is a duplicate, skip it.  */
	  skip = (last_path != 0 && (unsigned int) (p - this_path) == last_path_len
		  && ! strncmp (last_path, this_path, last_path_len));
Doug Evans committed
7400

Kazu Hirata committed
7401 7402
	  last_path = this_path;
	  last_path_len = p - this_path;
7403
	}
Doug Evans committed
7404

7405 7406 7407 7408 7409
      /* If this directory requires any default arguments, we can skip
	 it.  We will already have printed a directory identical to
	 this one which does not require that default argument.  */
      if (! skip)
	{
Zack Weinberg committed
7410
	  const char *q;
7411 7412 7413 7414

	  q = p + 1;
	  while (*q != ';')
	    {
Zack Weinberg committed
7415
	      const char *arg;
7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443

	      if (*q == '\0')
		abort ();

	      if (*q == '!')
		arg = NULL;
	      else
		arg = q;

	      while (*q != ' ' && *q != ';')
		{
		  if (*q == '\0')
		    abort ();
		  ++q;
		}

	      if (arg != NULL
		  && default_arg (arg, q - arg))
		{
		  skip = 1;
		  break;
		}

	      if (*q == ' ')
		++q;
	    }
	}

Doug Evans committed
7444 7445
      if (! skip)
	{
Zack Weinberg committed
7446
	  const char *p1;
Doug Evans committed
7447

7448
	  for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
Doug Evans committed
7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485
	    putchar (*p1);
	  putchar (';');
	}

      ++p;
      while (*p != ';')
	{
	  int use_arg;

	  if (*p == '\0')
	    abort ();

	  if (skip)
	    {
	      ++p;
	      continue;
	    }

	  use_arg = *p != '!';

	  if (use_arg)
	    putchar ('@');

	  while (*p != ' ' && *p != ';')
	    {
	      if (*p == '\0')
		abort ();
	      if (use_arg)
		putchar (*p);
	      ++p;
	    }

	  if (*p == ' ')
	    ++p;
	}

      if (! skip)
7486
	{
7487
	  /* If there are extra options, print them now.  */
7488 7489 7490
	  if (multilib_extra && *multilib_extra)
	    {
	      int print_at = TRUE;
Zack Weinberg committed
7491
	      const char *q;
7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505

	      for (q = multilib_extra; *q != '\0'; q++)
		{
		  if (*q == ' ')
		    print_at = TRUE;
		  else
		    {
		      if (print_at)
			putchar ('@');
		      putchar (*q);
		      print_at = FALSE;
		    }
		}
	    }
Kazu Hirata committed
7506

7507 7508
	  putchar ('\n');
	}
Doug Evans committed
7509 7510 7511 7512

      ++p;
    }
}
7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532

/* if-exists built-in spec function.

   Checks to see if the file specified by the absolute pathname in
   ARGS exists.  Returns that pathname if found.

   The usual use for this function is to check for a library file
   (whose name has been expanded with %s).  */

static const char *
if_exists_spec_function (argc, argv)
     int argc;
     const char **argv;
{
  /* Must have only one argument.  */
  if (argc == 1 && IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
    return argv[0];

  return NULL;
}
7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552

/* if-exists-else built-in spec function.

   This is like if-exists, but takes an additional argument which
   is returned if the first argument does not exist.  */

static const char *
if_exists_else_spec_function (argc, argv)
     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))
    return argv[0];

  return argv[1];
}