OSDN Git Service

(option_map): Make --version alias for -dumpversion.
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
1 /* Compiler driver program that can handle many languages.
2    Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 This paragraph is here to try to keep Sun CC from dying.
21 The number of chars here seems crucial!!!!  */
22
23 /* This program is the user interface to the C compiler and possibly to
24 other compilers.  It is used because compilation is a complicated procedure
25 which involves running several programs and passing temporary files between
26 them, forwarding the users switches to those programs selectively,
27 and deleting the temporary files at the end.
28
29 CC recognizes how to compile each input file by suffixes in the file names.
30 Once it knows which kind of compilation to perform, the procedure for
31 compilation is specified by a string called a "spec".  */
32 \f
33 #include <sys/types.h>
34 #include <ctype.h>
35 #include <signal.h>
36 #include <sys/stat.h>
37 #include <sys/file.h>   /* May get R_OK, etc. on some systems.  */
38
39 #include "config.h"
40 #include "obstack.h"
41 #include "gvarargs.h"
42 #include <stdio.h>
43
44 #ifndef R_OK
45 #define R_OK 4
46 #define W_OK 2
47 #define X_OK 1
48 #endif
49
50 /* Define a generic NULL if one hasn't already been defined.  */
51
52 #ifndef NULL
53 #define NULL 0
54 #endif
55
56 #ifndef GENERIC_PTR
57 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
58 #define GENERIC_PTR void *
59 #else
60 #define GENERIC_PTR char *
61 #endif
62 #endif
63
64 #ifndef NULL_PTR
65 #define NULL_PTR ((GENERIC_PTR)0)
66 #endif
67
68 #ifdef USG
69 #define vfork fork
70 #endif /* USG */
71
72 /* On MSDOS, write temp files in current dir
73    because there's no place else we can expect to use.  */
74 #if __MSDOS__
75 #ifndef P_tmpdir
76 #define P_tmpdir "./"
77 #endif
78 #endif
79
80 /* Test if something is a normal file.  */
81 #ifndef S_ISREG
82 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
83 #endif
84
85 /* Test if something is a directory.  */
86 #ifndef S_ISDIR
87 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
88 #endif
89
90 /* By default there is no special suffix for executables.  */
91 #ifndef EXECUTABLE_SUFFIX
92 #define EXECUTABLE_SUFFIX ""
93 #endif
94
95 /* By default, colon separates directories in a path.  */
96 #ifndef PATH_SEPARATOR
97 #define PATH_SEPARATOR ':'
98 #endif
99
100 #define obstack_chunk_alloc xmalloc
101 #define obstack_chunk_free free
102
103 extern void free ();
104 extern char *getenv ();
105
106 extern int errno, sys_nerr;
107 extern char *sys_errlist[];
108
109 extern int execv (), execvp ();
110
111 /* If a stage of compilation returns an exit status >= 1,
112    compilation of that file ceases.  */
113
114 #define MIN_FATAL_STATUS 1
115
116 /* Flag saying to print the full filename of libgcc.a
117    as found through our usual search mechanism.  */
118
119 static int print_libgcc_file_name;
120
121 /* Flag indicating whether we should print the command and arguments */
122
123 static int verbose_flag;
124
125 /* Nonzero means write "temp" files in source directory
126    and use the source file's name in them, and don't delete them.  */
127
128 static int save_temps_flag;
129
130 /* The compiler version specified with -V */
131
132 static char *spec_version;
133
134 /* The target machine specified with -b.  */
135
136 static char *spec_machine = DEFAULT_TARGET_MACHINE;
137
138 /* Nonzero if cross-compiling.
139    When -b is used, the value comes from the `specs' file.  */
140
141 #ifdef CROSS_COMPILE
142 static int cross_compile = 1;
143 #else
144 static int cross_compile = 0;
145 #endif
146
147 /* The number of errors that have occurred; the link phase will not be
148    run if this is non-zero.  */
149 static int error_count = 0;
150
151 /* This is the obstack which we use to allocate many strings.  */
152
153 static struct obstack obstack;
154
155 /* This is the obstack to build an environment variable to pass to
156    collect2 that describes all of the relevant switches of what to
157    pass the compiler in building the list of pointers to constructors
158    and destructors.  */
159
160 static struct obstack collect_obstack;
161
162 extern char *version_string;
163
164 static void set_spec ();
165 static struct compiler *lookup_compiler ();
166 static char *find_a_file ();
167 static void add_prefix ();
168 static char *skip_whitespace ();
169 static void record_temp_file ();
170 static char *handle_braces ();
171 static char *save_string ();
172 static char *concat ();
173 static int do_spec ();
174 static int do_spec_1 ();
175 static char *find_file ();
176 static int is_directory ();
177 static void validate_switches ();
178 static void validate_all_switches ();
179 static void give_switch ();
180 static void pfatal_with_name ();
181 static void perror_with_name ();
182 static void perror_exec ();
183 static void fatal ();
184 static void error ();
185 void fancy_abort ();
186 char *xmalloc ();
187 char *xrealloc ();
188 \f
189 /* Specs are strings containing lines, each of which (if not blank)
190 is made up of a program name, and arguments separated by spaces.
191 The program name must be exact and start from root, since no path
192 is searched and it is unreliable to depend on the current working directory.
193 Redirection of input or output is not supported; the subprograms must
194 accept filenames saying what files to read and write.
195
196 In addition, the specs can contain %-sequences to substitute variable text
197 or for conditional text.  Here is a table of all defined %-sequences.
198 Note that spaces are not generated automatically around the results of
199 expanding these sequences; therefore, you can concatenate them together
200 or with constant text in a single argument.
201
202  %%     substitute one % into the program name or argument.
203  %i     substitute the name of the input file being processed.
204  %b     substitute the basename of the input file being processed.
205         This is the substring up to (and not including) the last period
206         and not including the directory.
207  %g     substitute the temporary-file-name-base.  This is a string chosen
208         once per compilation.  Different temporary file names are made by
209         concatenation of constant strings on the end, as in `%g.s'.
210         %g also has the same effect of %d.
211  %u     like %g, but make the temporary file name unique.
212  %U     returns the last file name generated with %u.
213  %d     marks the argument containing or following the %d as a
214         temporary file name, so that that file will be deleted if CC exits
215         successfully.  Unlike %g, this contributes no text to the argument.
216  %w     marks the argument containing or following the %w as the
217         "output file" of this compilation.  This puts the argument
218         into the sequence of arguments that %o will substitute later.
219  %W{...}
220         like %{...} but mark last argument supplied within
221         as a file to be deleted on failure.
222  %o     substitutes the names of all the output files, with spaces
223         automatically placed around them.  You should write spaces
224         around the %o as well or the results are undefined.
225         %o is for use in the specs for running the linker.
226         Input files whose names have no recognized suffix are not compiled
227         at all, but they are included among the output files, so they will
228         be linked.
229  %p     substitutes the standard macro predefinitions for the
230         current target machine.  Use this when running cpp.
231  %P     like %p, but puts `__' before and after the name of each macro.
232         (Except macros that already have __.)
233         This is for ANSI C.
234  %I     Substitute a -iprefix option made from GCC_EXEC_PREFIX.
235  %s     current argument is the name of a library or startup file of some sort.
236         Search for that file in a standard list of directories
237         and substitute the full name found.
238  %eSTR  Print STR as an error message.  STR is terminated by a newline.
239         Use this when inconsistent options are detected.
240  %x{OPTION}     Accumulate an option for %X.
241  %X     Output the accumulated linker options specified by compilations.
242  %Y     Output the accumulated assembler options specified by compilations.
243  %a     process ASM_SPEC as a spec.
244         This allows config.h to specify part of the spec for running as.
245  %A     process ASM_FINAL_SPEC as a spec.  A capital A is actually
246         used here.  This can be used to run a post-processor after the
247         assembler has done it's job.
248  %D     Dump out a -L option for each directory in startfile_prefix.
249  %l     process LINK_SPEC as a spec.
250  %L     process LIB_SPEC as a spec.
251  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
252  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
253  %c     process SIGNED_CHAR_SPEC as a spec.
254  %C     process CPP_SPEC as a spec.  A capital C is actually used here.
255  %1     process CC1_SPEC as a spec.
256  %2     process CC1PLUS_SPEC as a spec.
257  %|     output "-" if the input for the current command is coming from a pipe.
258  %*     substitute the variable part of a matched option.  (See below.)
259         Note that each comma in the substituted string is replaced by
260         a single space.
261  %{S}   substitutes the -S switch, if that switch was given to CC.
262         If that switch was not specified, this substitutes nothing.
263         Here S is a metasyntactic variable.
264  %{S*}  substitutes all the switches specified to CC whose names start
265         with -S.  This is used for -o, -D, -I, etc; switches that take
266         arguments.  CC considers `-o foo' as being one switch whose
267         name starts with `o'.  %{o*} would substitute this text,
268         including the space; thus, two arguments would be generated.
269  %{S*:X} substitutes X if one or more switches whose names start with -S are
270         specified to CC.  Note that the tail part of the -S option
271         (i.e. the part matched by the `*') will be substituted for each
272         occurrence of %* within X.
273  %{S:X} substitutes X, but only if the -S switch was given to CC.
274  %{!S:X} substitutes X, but only if the -S switch was NOT given to CC.
275  %{|S:X} like %{S:X}, but if no S switch, substitute `-'.
276  %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
277  %{.S:X} substitutes X, but only if processing a file with suffix S.
278  %{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
279  %(Spec) processes a specification defined in a specs file as *Spec:
280  %[Spec] as above, but put __ around -D arguments
281
282 The conditional text X in a %{S:X} or %{!S:X} construct may contain
283 other nested % constructs or spaces, or even newlines.  They are
284 processed as usual, as described above.
285
286 The character | is used to indicate that a command should be piped to
287 the following command, but only if -pipe is specified.
288
289 Note that it is built into CC which switches take arguments and which
290 do not.  You might think it would be useful to generalize this to
291 allow each compiler's spec to say which switches take arguments.  But
292 this cannot be done in a consistent fashion.  CC cannot even decide
293 which input files have been specified without knowing which switches
294 take arguments, and it must know which input files to compile in order
295 to tell which compilers to run.
296
297 CC also knows implicitly that arguments starting in `-l' are to be
298 treated as compiler output files, and passed to the linker in their
299 proper position among the other output files.  */
300 \f
301 /* Define the macros used for specs %a, %l, %L, %S, %c, %C, %1.  */
302
303 /* config.h can define ASM_SPEC to provide extra args to the assembler
304    or extra switch-translations.  */
305 #ifndef ASM_SPEC
306 #define ASM_SPEC ""
307 #endif
308
309 /* config.h can define ASM_FINAL_SPEC to run a post processor after
310    the assembler has run.  */
311 #ifndef ASM_FINAL_SPEC
312 #define ASM_FINAL_SPEC ""
313 #endif
314
315 /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
316    or extra switch-translations.  */
317 #ifndef CPP_SPEC
318 #define CPP_SPEC ""
319 #endif
320
321 /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
322    or extra switch-translations.  */
323 #ifndef CC1_SPEC
324 #define CC1_SPEC ""
325 #endif
326
327 /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
328    or extra switch-translations.  */
329 #ifndef CC1PLUS_SPEC
330 #define CC1PLUS_SPEC ""
331 #endif
332
333 /* config.h can define LINK_SPEC to provide extra args to the linker
334    or extra switch-translations.  */
335 #ifndef LINK_SPEC
336 #define LINK_SPEC ""
337 #endif
338
339 /* config.h can define LIB_SPEC to override the default libraries.  */
340 #ifndef LIB_SPEC
341 #define LIB_SPEC "%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
342 #endif
343
344 /* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
345 #ifndef STARTFILE_SPEC
346 #define STARTFILE_SPEC  \
347   "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
348 #endif
349
350 /* config.h can define SWITCHES_NEED_SPACES to control passing -o and -L.
351    Make the string nonempty to require spaces there.  */
352 #ifndef SWITCHES_NEED_SPACES
353 #define SWITCHES_NEED_SPACES ""
354 #endif
355
356 /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
357 #ifndef ENDFILE_SPEC
358 #define ENDFILE_SPEC ""
359 #endif
360
361 /* This spec is used for telling cpp whether char is signed or not.  */
362 #ifndef SIGNED_CHAR_SPEC
363 /* Use #if rather than ?:
364    because MIPS C compiler rejects like ?: in initializers.  */
365 #if DEFAULT_SIGNED_CHAR
366 #define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
367 #else
368 #define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}"
369 #endif
370 #endif
371
372 static char *cpp_spec = CPP_SPEC;
373 static char *cpp_predefines = CPP_PREDEFINES;
374 static char *cc1_spec = CC1_SPEC;
375 static char *cc1plus_spec = CC1PLUS_SPEC;
376 static char *signed_char_spec = SIGNED_CHAR_SPEC;
377 static char *asm_spec = ASM_SPEC;
378 static char *asm_final_spec = ASM_FINAL_SPEC;
379 static char *link_spec = LINK_SPEC;
380 static char *lib_spec = LIB_SPEC;
381 static char *endfile_spec = ENDFILE_SPEC;
382 static char *startfile_spec = STARTFILE_SPEC;
383 static char *switches_need_spaces = SWITCHES_NEED_SPACES;
384
385 /* This defines which switch letters take arguments.  */
386
387 #ifndef SWITCH_TAKES_ARG
388 #define SWITCH_TAKES_ARG(CHAR)      \
389   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
390    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
391    || (CHAR) == 'I' || (CHAR) == 'm' \
392    || (CHAR) == 'L' || (CHAR) == 'A')
393 #endif
394
395 /* This defines which multi-letter switches take arguments.  */
396
397 #define DEFAULT_WORD_SWITCH_TAKES_ARG(STR)              \
398  (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext")      \
399   || !strcmp (STR, "Tbss") || !strcmp (STR, "include")  \
400   || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
401   || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
402   || !strcmp (STR, "iwithprefix"))
403
404 #ifndef WORD_SWITCH_TAKES_ARG
405 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
406 #endif
407 \f
408 /* Record the mapping from file suffixes for compilation specs.  */
409
410 struct compiler
411 {
412   char *suffix;                 /* Use this compiler for input files
413                                    whose names end in this suffix.  */
414
415   char *spec[4];                /* To use this compiler, concatenate these
416                                    specs and pass to do_spec.  */
417 };
418
419 /* Pointer to a vector of `struct compiler' that gives the spec for
420    compiling a file, based on its suffix.
421    A file that does not end in any of these suffixes will be passed
422    unchanged to the loader and nothing else will be done to it.
423
424    An entry containing two 0s is used to terminate the vector.
425
426    If multiple entries match a file, the last matching one is used.  */
427
428 static struct compiler *compilers;
429
430 /* Number of entries in `compilers', not counting the null terminator.  */
431
432 static int n_compilers;
433
434 /* The default list of file name suffixes and their compilation specs.  */
435
436 static struct compiler default_compilers[] =
437 {
438   {".c", "@c"},
439   {"@c",
440    "cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
441         %{C:%{!E:%eGNU C does not support -C without using -E}}\
442         %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\
443         -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
444         %{!undef:%{!ansi:%p} %P} %{trigraphs} \
445         %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
446         %{traditional-cpp:-traditional}\
447         %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
448         %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
449    "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \
450                    %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\
451                    %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
452                    %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
453                    %{aux-info*}\
454                    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
455                    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
456               %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
457                       %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
458                       %{!pipe:%g.s} %A\n }}}}"},
459   {"-",
460    "%{E:cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
461         %{C:%{!E:%eGNU C does not support -C without using -E}}\
462         %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\
463         -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
464         %{!undef:%{!ansi:%p} %P} %{trigraphs}\
465         %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
466         %{traditional-cpp:-traditional}\
467         %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
468         %i %W{o*}}\
469     %{!E:%e-E required when input is from standard input}"},
470   {".m", "@objective-c"},
471   {"@objective-c",
472    "cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
473         %{C:%{!E:%eGNU C does not support -C without using -E}}\
474         %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\
475         -undef -D__OBJC__ -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
476         %{!undef:%{!ansi:%p} %P} %{trigraphs}\
477         %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
478         %{traditional-cpp:-traditional}\
479         %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
480         %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
481    "%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.i} %1 \
482                    %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a}\
483                    %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
484                    %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \
485                    -lang-objc %{gen-decls} \
486                    %{aux-info*}\
487                    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
488                    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
489               %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
490                       %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
491                       %{!pipe:%g.s} %A\n }}}}"},
492   {".h", "@c-header"},
493   {"@c-header",
494    "%{!E:%eCompilation of header file requested} \
495     cpp %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
496         %{C:%{!E:%eGNU C does not support -C without using -E}}\
497          %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \
498         -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
499         %{!undef:%{!ansi:%p} %P} %{trigraphs}\
500         %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
501         %{traditional-cpp:-traditional}\
502         %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
503         %i %W{o*}"},
504   {".cc", "@c++"},
505   {".cxx", "@c++"},
506   {".C", "@c++"},
507   {"@c++",
508    "cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
509         %{C:%{!E:%eGNU C++ does not support -C without using -E}}\
510         %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \
511         -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus \
512         %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
513         %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
514         %{traditional-cpp:-traditional} %{trigraphs}\
515         %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
516         %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
517    "%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.i} %1 %2\
518                    %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
519                    %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
520                    %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
521                    %{aux-info*}\
522                    %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
523                    %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
524               %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
525                       %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
526                       %{!pipe:%g.s} %A\n }}}}"},
527   {".i", "@cpp-output"},
528   {"@cpp-output",
529    "cc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\
530         %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
531         %{v:-version} %{pg:-p} %{p} %{f*}\
532         %{aux-info*}\
533         %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
534         %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
535     %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
536             %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %{!pipe:%g.s} %A\n }"},
537   {".ii", "@c++-cpp-output"},
538   {"@c++-cpp-output",
539    "cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
540             %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
541             %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
542             %{aux-info*}\
543             %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
544             %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
545        %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
546                %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
547                %{!pipe:%g.s} %A\n }"},
548   {".s", "@assembler"},
549   {"@assembler",
550    "%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
551             %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %i %A\n }"},
552   {".S", "@assembler-with-cpp"},
553   {"@assembler-with-cpp",
554    "cpp -lang-asm %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
555         %{C:%{!E:%eGNU C does not support -C without using -E}}\
556         %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{trigraphs} \
557         -undef -$ %{!undef:%p %P} -D__ASSEMBLER__ \
558         %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
559         %{traditional-cpp:-traditional}\
560         %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
561         %i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
562    "%{!M:%{!MM:%{!E:%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
563                     %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
564                     %{!pipe:%g.s} %A\n }}}}"},
565   /* Mark end of table */
566   {0, 0}
567 };
568
569 /* Number of elements in default_compilers, not counting the terminator.  */
570
571 static int n_default_compilers
572   = (sizeof default_compilers / sizeof (struct compiler)) - 1;
573
574 /* Here is the spec for running the linker, after compiling all files.  */
575
576 /* -u* was put back because both BSD and SysV seem to support it.  */
577 /* %{static:} simply prevents an error message if the target machine
578    doesn't handle -static.  */
579 #ifdef LINK_LIBGCC_SPECIAL_1
580 /* Have gcc do the search for libgcc.a, but generate -L options as usual.  */
581 static char *link_command_spec = "\
582 %{!fsyntax-only: \
583  %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
584                         %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\
585                         %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
586                         %{L*} %D %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
587 #else
588 #ifdef LINK_LIBGCC_SPECIAL
589 /* Have gcc do the search for libgcc.a, and don't generate -L options.  */
590 static char *link_command_spec = "\
591 %{!fsyntax-only: \
592  %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
593                         %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\
594                         %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
595                         %{L*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
596 #else
597 /* Use -L and have the linker do the search for -lgcc.  */
598 static char *link_command_spec = "\
599 %{!fsyntax-only: \
600  %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
601                         %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\
602                         %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
603                         %{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}}";
604 #endif
605 #endif
606
607 /* A vector of options to give to the linker.
608    These options are accumulated by -Xlinker and -Wl,
609    and substituted into the linker command with %X.  */
610 static int n_linker_options;
611 static char **linker_options;
612
613 /* A vector of options to give to the assembler.
614    These options are accumulated by -Wa,
615    and substituted into the assembler command with %X.  */
616 static int n_assembler_options;
617 static char **assembler_options;
618 \f
619 /* Define how to map long options into short ones.  */
620
621 /* This structure describes one mapping.  */
622 struct option_map
623 {
624   /* The long option's name.  */
625   char *name;
626   /* The equivalent short option.  */
627   char *equivalent;
628   /* Argument info.  A string of flag chars; NULL equals no options.
629      a => argument required.
630      o => argument optional.
631      j => join argument to equivalent, making one word.
632      * => allow other text after NAME as an argument.  */
633   char *arg_info;
634 };
635
636 /* This is the table of mappings.  Mappings are tried sequentially
637    for each option encountered; the first one that matches, wins.  */
638
639 struct option_map option_map[] =
640  {
641    {"--profile-blocks", "-a", 0},
642    {"--target", "-b", "a"},
643    {"--compile", "-c", 0},
644    {"--dump", "-d", "a"},
645    {"--entry", "-e", 0},
646    {"--debug", "-g", "oj"},
647    {"--include", "-include", "a"},
648    {"--imacros", "-imacros", "a"},
649    {"--include-prefix", "-iprefix", "a"},
650    {"--include-directory-after", "-idirafter", "a"},
651    {"--include-with-prefix", "-iwithprefix", "a"},
652    {"--machine-", "-m", "*j"},
653    {"--machine", "-m", "aj"},
654    {"--no-standard-includes", "-nostdinc", 0},
655    {"--no-standard-libraries", "-nostdlib", 0},
656    {"--no-precompiled-includes", "-noprecomp", 0},
657    {"--output", "-o", "a"},
658    {"--profile", "-p", 0},
659    {"--quiet", "-q", 0},
660    {"--silent", "-q", 0},
661    {"--force-link", "-u", "a"},
662    {"--verbose", "-v", 0},
663    {"--version", "-dumpversion", 0}
664    {"--no-warnings", "-w", 0},
665    {"--language", "-x", "a"},
666
667    {"--assert", "-A", "a"},
668    {"--prefix", "-B", "a"},
669    {"--comments", "-C", 0},
670    {"--define-macro", "-D", "a"},
671    {"--preprocess", "-E", 0},
672    {"--trace-includes", "-H", 0},
673    {"--include-directory", "-I", "a"},
674    {"--include-barrier", "-I-", 0},
675    {"--library-directory", "-L", "a"},
676    {"--dependencies", "-M", 0},
677    {"--user-dependencies", "-MM", 0},
678    {"--write-dependencies", "-MD", 0},
679    {"--write-user-dependencies", "-MMD", 0},
680    {"--optimize", "-O", "oj"},
681    {"--no-line-commands", "-P", 0},
682    {"--assemble", "-S", 0},
683    {"--undefine-macro", "-U", "a"},
684    {"--use-version", "-V", "a"},
685    {"--for-assembler", "-Wa", "a"},
686    {"--extra-warnings", "-W", 0},
687    {"--all-warnings", "-Wall", 0},
688    {"--warn-", "-W", "*j"},
689    {"--for-linker", "-Xlinker", "a"},
690
691    {"--ansi", "-ansi", 0},
692    {"--traditional", "-traditional", 0},
693    {"--traditional-cpp", "-traditional-cpp", 0},
694    {"--trigraphs", "-trigraphs", 0},
695    {"--pipe", "-pipe", 0},
696    {"--dumpbase", "-dumpbase", "a"},
697    {"--pedantic", "-pedantic", 0},
698    {"--pedantic-errors", "-pedantic-errors", 0},
699    {"--save-temps", "-save-temps", 0},
700    {"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
701    {"--static", "-static", 0},
702    {"--shared", "-shared", 0},
703    {"--symbolic", "-symbolic", 0},
704    {"--", "-f", "*j"}
705  };
706 \f
707 /* Translate the options described by *ARGCP and *ARGVP.
708    Make a new vector and store it back in *ARGVP,
709    and store its length in *ARGVC.  */
710
711 static void
712 translate_options (argcp, argvp)
713      int *argcp;
714      char ***argvp;
715 {
716   int i, j;
717   int argc = *argcp;
718   char **argv = *argvp;
719   char **newv = (char **) xmalloc ((argc + 2) * 2 * sizeof (char *));
720   int newindex = 0;
721
722   i = 0;
723   newv[newindex++] = argv[i++];
724
725   while (i < argc)
726     {
727       /* Translate -- options.  */
728       if (argv[i][0] == '-' && argv[i][1] == '-')
729         {
730           /* Find a mapping that applies to this option.  */
731           for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++)
732             {
733               int optlen = strlen (option_map[j].name);
734               int complen = strlen (argv[i]);
735               char *arginfo = option_map[j].arg_info;
736
737               if (arginfo == 0)
738                 arginfo = "";
739               if (complen > optlen)
740                 complen = optlen;
741               if (!strncmp (argv[i], option_map[j].name, complen))
742                 {
743                   int extra = strlen (argv[i]) > optlen;
744                   char *arg = 0;
745
746                   if (extra)
747                     {
748                       /* If the option has an argument, accept that.  */
749                       if (argv[i][optlen] == '=')
750                         arg = argv[i] + optlen + 1;
751                       /* If this mapping allows extra text at end of name,
752                          accept that as "argument".  */
753                       else if (index (arginfo, '*') != 0)
754                         arg = argv[i] + optlen;
755                       /* Otherwise, extra text at end means mismatch.
756                          Try other mappings.  */
757                       else
758                         continue;
759                     }
760                   else if (index (arginfo, '*') != 0)
761                     error ("Incomplete `%s' option", option_map[j].name);
762
763                   /* Handle arguments.  */
764                   if (index (arginfo, 'o') != 0)
765                     {
766                       if (arg == 0)
767                         {
768                           if (i + 1 == argc)
769                             error ("Missing argument to `%s' option",
770                                    option_map[j].name);
771                           arg = argv[++i];
772                         }
773                     }
774                   else if (index (arginfo, 'a') == 0)
775                     {
776                       if (arg != 0)
777                         error ("Extraneous argument to `%s' option",
778                                option_map[j].name);
779                       arg = 0;
780                     }
781
782                   /* Store the translation as one argv elt or as two.  */
783                   if (arg != 0 && index (arginfo, 'j') != 0)
784                     newv[newindex++] = concat (option_map[j].equivalent,
785                                                arg, "");
786                   else if (arg != 0)
787                     {
788                       newv[newindex++] = option_map[j].equivalent;
789                       newv[newindex++] = arg;
790                     }
791                   else
792                     newv[newindex++] = option_map[j].equivalent;
793
794                   break;
795                 }
796             }
797           i++;
798         }
799       /* Handle old-fashioned options--just copy them through,
800          with their arguments.  */
801       else if (argv[i][0] == '-')
802         {
803           char *p = argv[i] + 1;
804           int c = *p;
805           int nskip = 1;
806
807           if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
808             nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
809           else if (WORD_SWITCH_TAKES_ARG (p))
810             nskip += WORD_SWITCH_TAKES_ARG (p);
811
812           while (nskip > 0)
813             {
814               newv[newindex++] = argv[i++];
815               nskip--;
816             }
817         }
818       else
819         /* Ordinary operands, or +e options.  */
820         newv[newindex++] = argv[i++];
821     }
822
823   newv[newindex] = 0;
824
825   *argvp = newv;
826   *argcp = newindex;
827 }
828 \f
829 /* Read compilation specs from a file named FILENAME,
830    replacing the default ones.
831
832    A suffix which starts with `*' is a definition for
833    one of the machine-specific sub-specs.  The "suffix" should be
834    *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc.
835    The corresponding spec is stored in asm_spec, etc.,
836    rather than in the `compilers' vector.
837
838    Anything invalid in the file is a fatal error.  */
839
840 static void
841 read_specs (filename)
842      char *filename;
843 {
844   int desc;
845   struct stat statbuf;
846   char *buffer;
847   register char *p;
848
849   if (verbose_flag)
850     fprintf (stderr, "Reading specs from %s\n", filename);
851
852   /* Open and stat the file.  */
853   desc = open (filename, 0, 0);
854   if (desc < 0)
855     pfatal_with_name (filename);
856   if (stat (filename, &statbuf) < 0)
857     pfatal_with_name (filename);
858
859   /* Read contents of file into BUFFER.  */
860   buffer = xmalloc ((unsigned) statbuf.st_size + 1);
861   read (desc, buffer, (unsigned) statbuf.st_size);
862   buffer[statbuf.st_size] = 0;
863   close (desc);
864
865   /* Scan BUFFER for specs, putting them in the vector.  */
866   p = buffer;
867   while (1)
868     {
869       char *suffix;
870       char *spec;
871       char *in, *out, *p1, *p2;
872
873       /* Advance P in BUFFER to the next nonblank nocomment line.  */
874       p = skip_whitespace (p);
875       if (*p == 0)
876         break;
877
878       /* Find the colon that should end the suffix.  */
879       p1 = p;
880       while (*p1 && *p1 != ':' && *p1 != '\n') p1++;
881       /* The colon shouldn't be missing.  */
882       if (*p1 != ':')
883         fatal ("specs file malformed after %d characters", p1 - buffer);
884       /* Skip back over trailing whitespace.  */
885       p2 = p1;
886       while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--;
887       /* Copy the suffix to a string.  */
888       suffix = save_string (p, p2 - p);
889       /* Find the next line.  */
890       p = skip_whitespace (p1 + 1);
891       if (p[1] == 0)
892         fatal ("specs file malformed after %d characters", p - buffer);
893       p1 = p;
894       /* Find next blank line.  */
895       while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++;
896       /* Specs end at the blank line and do not include the newline.  */
897       spec = save_string (p, p1 - p);
898       p = p1;
899
900       /* Delete backslash-newline sequences from the spec.  */
901       in = spec;
902       out = spec;
903       while (*in != 0)
904         {
905           if (in[0] == '\\' && in[1] == '\n')
906             in += 2;
907           else if (in[0] == '#')
908             {
909               while (*in && *in != '\n') in++;
910             }
911           else
912             *out++ = *in++;
913         }
914       *out = 0;
915
916       if (suffix[0] == '*')
917         {
918           if (! strcmp (suffix, "*link_command"))
919             link_command_spec = spec;
920           else
921             set_spec (suffix + 1, spec);
922         }
923       else
924         {
925           /* Add this pair to the vector.  */
926           compilers
927             = ((struct compiler *)
928                xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler)));
929           compilers[n_compilers].suffix = suffix;
930           bzero (compilers[n_compilers].spec,
931                  sizeof compilers[n_compilers].spec);
932           compilers[n_compilers].spec[0] = spec;
933           n_compilers++;
934         }
935
936       if (*suffix == 0)
937         link_command_spec = spec;
938     }
939
940   if (link_command_spec == 0)
941     fatal ("spec file has no spec for linking");
942 }
943
944 static char *
945 skip_whitespace (p)
946      char *p;
947 {
948   while (1)
949     {
950       /* A fully-blank line is a delimiter in the SPEC file and shouldn't
951          be considered whitespace.  */
952       if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
953         return p + 1;
954       else if (*p == '\n' || *p == ' ' || *p == '\t')
955         p++;
956       else if (*p == '#')
957         {
958           while (*p != '\n') p++;
959           p++;
960         }
961       else
962         break;
963     }
964
965   return p;
966 }
967 \f
968 /* Structure to keep track of the specs that have been defined so far.  These
969    are accessed using %(specname) or %[specname] in a compiler or link spec. */
970
971 struct spec_list
972 {
973   char *name;                 /* Name of the spec. */
974   char *spec;                 /* The spec itself. */
975   struct spec_list *next;     /* Next spec in linked list. */
976 };
977
978 /* List of specs that have been defined so far. */
979
980 static struct spec_list *specs = (struct spec_list *) 0;
981 \f
982 /* Change the value of spec NAME to SPEC.  If SPEC is empty, then the spec is
983    removed; If the spec starts with a + then SPEC is added to the end of the
984    current spec. */
985
986 static void
987 set_spec (name, spec)
988      char *name;
989      char *spec;
990 {
991   struct spec_list *sl;
992   char *old_spec;
993
994   /* See if the spec already exists */
995   for (sl = specs; sl; sl = sl->next)
996     if (strcmp (sl->name, name) == 0)
997       break;
998
999   if (!sl)
1000     {
1001       /* Not found - make it */
1002       sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
1003       sl->name = save_string (name, strlen (name));
1004       sl->spec = save_string ("", 0);
1005       sl->next = specs;
1006       specs = sl;
1007     }
1008
1009   old_spec = sl->spec;
1010   if (name && spec[0] == '+' && isspace (spec[1]))
1011     sl->spec = concat (old_spec, spec + 1, "");
1012   else
1013     sl->spec = save_string (spec, strlen (spec));
1014
1015   if (! strcmp (name, "asm"))
1016     asm_spec = sl->spec;
1017   else if (! strcmp (name, "asm_final"))
1018     asm_final_spec = sl->spec;
1019   else if (! strcmp (name, "cc1"))
1020     cc1_spec = sl->spec;
1021   else if (! strcmp (name, "cc1plus"))
1022     cc1plus_spec = sl->spec;
1023   else if (! strcmp (name, "cpp"))
1024     cpp_spec = sl->spec;
1025   else if (! strcmp (name, "endfile"))
1026     endfile_spec = sl->spec;
1027   else if (! strcmp (name, "lib"))
1028     lib_spec = sl->spec;
1029   else if (! strcmp (name, "link"))
1030     link_spec = sl->spec;
1031   else if (! strcmp (name, "predefines"))
1032     cpp_predefines = sl->spec;
1033   else if (! strcmp (name, "signed_char"))
1034     signed_char_spec = sl->spec;
1035   else if (! strcmp (name, "startfile"))
1036     startfile_spec = sl->spec;
1037   else if (! strcmp (name, "switches_need_spaces"))
1038     switches_need_spaces = sl->spec;
1039   else if (! strcmp (name, "cross_compile"))
1040     cross_compile = atoi (sl->spec);
1041   /* Free the old spec */
1042   if (old_spec)
1043     free (old_spec);
1044 }
1045 \f
1046 /* Accumulate a command (program name and args), and run it.  */
1047
1048 /* Vector of pointers to arguments in the current line of specifications.  */
1049
1050 static char **argbuf;
1051
1052 /* Number of elements allocated in argbuf.  */
1053
1054 static int argbuf_length;
1055
1056 /* Number of elements in argbuf currently in use (containing args).  */
1057
1058 static int argbuf_index;
1059
1060 /* This is the list of suffixes and codes (%g/%u/%U) and the associated
1061    temp file.  Used only if MKTEMP_EACH_FILE.  */
1062
1063 static struct temp_name {
1064   char *suffix;         /* suffix associated with the code.  */
1065   int length;           /* strlen (suffix).  */
1066   int unique;           /* Indicates whether %g or %u/%U was used.  */
1067   char *filename;       /* associated filename.  */
1068   int filename_length;  /* strlen (filename).  */
1069   struct temp_name *next;
1070 } *temp_names;
1071
1072 /* Number of commands executed so far.  */
1073
1074 static int execution_count;
1075
1076 /* Number of commands that exited with a signal.  */
1077
1078 static int signal_count;
1079
1080 /* Name with which this program was invoked.  */
1081
1082 static char *programname;
1083 \f
1084 /* Structures to keep track of prefixes to try when looking for files. */
1085
1086 struct prefix_list
1087 {
1088   char *prefix;               /* String to prepend to the path. */
1089   struct prefix_list *next;   /* Next in linked list. */
1090   int require_machine_suffix; /* Don't use without machine_suffix.  */
1091   /* 2 means try both machine_suffix and just_machine_suffix.  */
1092   int *used_flag_ptr;         /* 1 if a file was found with this prefix.  */
1093 };
1094
1095 struct path_prefix
1096 {
1097   struct prefix_list *plist;  /* List of prefixes to try */
1098   int max_len;                /* Max length of a prefix in PLIST */
1099   char *name;                 /* Name of this list (used in config stuff) */
1100 };
1101
1102 /* List of prefixes to try when looking for executables. */
1103
1104 static struct path_prefix exec_prefix = { 0, 0, "exec" };
1105
1106 /* List of prefixes to try when looking for startup (crt0) files. */
1107
1108 static struct path_prefix startfile_prefix = { 0, 0, "startfile" };
1109
1110 /* Suffix to attach to directories searched for commands.
1111    This looks like `MACHINE/VERSION/'.  */
1112
1113 static char *machine_suffix = 0;
1114
1115 /* Suffix to attach to directories searched for commands.
1116    This is just `MACHINE/'.  */
1117
1118 static char *just_machine_suffix = 0;
1119
1120 /* Adjusted value of GCC_EXEC_PREFIX envvar.  */
1121
1122 static char *gcc_exec_prefix;
1123
1124 /* Default prefixes to attach to command names.  */
1125
1126 #ifdef CROSS_COMPILE  /* Don't use these prefixes for a cross compiler.  */
1127 #undef MD_EXEC_PREFIX
1128 #undef MD_STARTFILE_PREFIX
1129 #undef MD_STARTFILE_PREFIX_1
1130 #endif
1131
1132 #ifndef STANDARD_EXEC_PREFIX
1133 #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
1134 #endif /* !defined STANDARD_EXEC_PREFIX */
1135
1136 static char *standard_exec_prefix = STANDARD_EXEC_PREFIX;
1137 static char *standard_exec_prefix_1 = "/usr/lib/gcc/";
1138 #ifdef MD_EXEC_PREFIX
1139 static char *md_exec_prefix = MD_EXEC_PREFIX;
1140 #endif
1141
1142 #ifndef STANDARD_STARTFILE_PREFIX
1143 #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
1144 #endif /* !defined STANDARD_STARTFILE_PREFIX */
1145
1146 #ifdef MD_STARTFILE_PREFIX
1147 static char *md_startfile_prefix = MD_STARTFILE_PREFIX;
1148 #endif
1149 #ifdef MD_STARTFILE_PREFIX_1
1150 static char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
1151 #endif
1152 static char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
1153 static char *standard_startfile_prefix_1 = "/lib/";
1154 static char *standard_startfile_prefix_2 = "/usr/lib/";
1155
1156 #ifndef TOOLDIR_BASE_PREFIX
1157 #define TOOLDIR_BASE_PREFIX "/usr/local/"
1158 #endif
1159 static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
1160 static char *tooldir_prefix;
1161
1162 /* Clear out the vector of arguments (after a command is executed).  */
1163
1164 static void
1165 clear_args ()
1166 {
1167   argbuf_index = 0;
1168 }
1169
1170 /* Add one argument to the vector at the end.
1171    This is done when a space is seen or at the end of the line.
1172    If DELETE_ALWAYS is nonzero, the arg is a filename
1173     and the file should be deleted eventually.
1174    If DELETE_FAILURE is nonzero, the arg is a filename
1175     and the file should be deleted if this compilation fails.  */
1176
1177 static void
1178 store_arg (arg, delete_always, delete_failure)
1179      char *arg;
1180      int delete_always, delete_failure;
1181 {
1182   if (argbuf_index + 1 == argbuf_length)
1183     {
1184       argbuf = (char **) xrealloc (argbuf, (argbuf_length *= 2) * sizeof (char *));
1185     }
1186
1187   argbuf[argbuf_index++] = arg;
1188   argbuf[argbuf_index] = 0;
1189
1190   if (delete_always || delete_failure)
1191     record_temp_file (arg, delete_always, delete_failure);
1192 }
1193 \f
1194 /* Record the names of temporary files we tell compilers to write,
1195    and delete them at the end of the run.  */
1196
1197 /* This is the common prefix we use to make temp file names.
1198    It is chosen once for each run of this program.
1199    It is substituted into a spec by %g.
1200    Thus, all temp file names contain this prefix.
1201    In practice, all temp file names start with this prefix.
1202
1203    This prefix comes from the envvar TMPDIR if it is defined;
1204    otherwise, from the P_tmpdir macro if that is defined;
1205    otherwise, in /usr/tmp or /tmp.  */
1206
1207 static char *temp_filename;
1208
1209 /* Length of the prefix.  */
1210
1211 static int temp_filename_length;
1212
1213 /* Define the list of temporary files to delete.  */
1214
1215 struct temp_file
1216 {
1217   char *name;
1218   struct temp_file *next;
1219 };
1220
1221 /* Queue of files to delete on success or failure of compilation.  */
1222 static struct temp_file *always_delete_queue;
1223 /* Queue of files to delete on failure of compilation.  */
1224 static struct temp_file *failure_delete_queue;
1225
1226 /* Record FILENAME as a file to be deleted automatically.
1227    ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
1228    otherwise delete it in any case.
1229    FAIL_DELETE nonzero means delete it if a compilation step fails;
1230    otherwise delete it in any case.  */
1231
1232 static void
1233 record_temp_file (filename, always_delete, fail_delete)
1234      char *filename;
1235      int always_delete;
1236      int fail_delete;
1237 {
1238   register char *name;
1239   name = xmalloc (strlen (filename) + 1);
1240   strcpy (name, filename);
1241
1242   if (always_delete)
1243     {
1244       register struct temp_file *temp;
1245       for (temp = always_delete_queue; temp; temp = temp->next)
1246         if (! strcmp (name, temp->name))
1247           goto already1;
1248       temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
1249       temp->next = always_delete_queue;
1250       temp->name = name;
1251       always_delete_queue = temp;
1252     already1:;
1253     }
1254
1255   if (fail_delete)
1256     {
1257       register struct temp_file *temp;
1258       for (temp = failure_delete_queue; temp; temp = temp->next)
1259         if (! strcmp (name, temp->name))
1260           goto already2;
1261       temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
1262       temp->next = failure_delete_queue;
1263       temp->name = name;
1264       failure_delete_queue = temp;
1265     already2:;
1266     }
1267 }
1268
1269 /* Delete all the temporary files whose names we previously recorded.  */
1270
1271 static void
1272 delete_temp_files ()
1273 {
1274   register struct temp_file *temp;
1275
1276   for (temp = always_delete_queue; temp; temp = temp->next)
1277     {
1278 #ifdef DEBUG
1279       int i;
1280       printf ("Delete %s? (y or n) ", temp->name);
1281       fflush (stdout);
1282       i = getchar ();
1283       if (i != '\n')
1284         while (getchar () != '\n') ;
1285       if (i == 'y' || i == 'Y')
1286 #endif /* DEBUG */
1287         {
1288           struct stat st;
1289           if (stat (temp->name, &st) >= 0)
1290             {
1291               /* Delete only ordinary files.  */
1292               if (S_ISREG (st.st_mode))
1293                 if (unlink (temp->name) < 0)
1294                   if (verbose_flag)
1295                     perror_with_name (temp->name);
1296             }
1297         }
1298     }
1299
1300   always_delete_queue = 0;
1301 }
1302
1303 /* Delete all the files to be deleted on error.  */
1304
1305 static void
1306 delete_failure_queue ()
1307 {
1308   register struct temp_file *temp;
1309
1310   for (temp = failure_delete_queue; temp; temp = temp->next)
1311     {
1312 #ifdef DEBUG
1313       int i;
1314       printf ("Delete %s? (y or n) ", temp->name);
1315       fflush (stdout);
1316       i = getchar ();
1317       if (i != '\n')
1318         while (getchar () != '\n') ;
1319       if (i == 'y' || i == 'Y')
1320 #endif /* DEBUG */
1321         {
1322           if (unlink (temp->name) < 0)
1323             if (verbose_flag)
1324               perror_with_name (temp->name);
1325         }
1326     }
1327 }
1328
1329 static void
1330 clear_failure_queue ()
1331 {
1332   failure_delete_queue = 0;
1333 }
1334
1335 /* Compute a string to use as the base of all temporary file names.
1336    It is substituted for %g.  */
1337
1338 static void
1339 choose_temp_base ()
1340 {
1341   char *base = getenv ("TMPDIR");
1342   int len;
1343
1344   if (base == (char *)0)
1345     {
1346 #ifdef P_tmpdir
1347       if (access (P_tmpdir, R_OK | W_OK) == 0)
1348         base = P_tmpdir;
1349 #endif
1350       if (base == (char *)0)
1351         {
1352           if (access ("/usr/tmp", R_OK | W_OK) == 0)
1353             base = "/usr/tmp/";
1354           else
1355             base = "/tmp/";
1356         }
1357     }
1358
1359   len = strlen (base);
1360   temp_filename = xmalloc (len + sizeof("/ccXXXXXX"));
1361   strcpy (temp_filename, base);
1362   if (len > 0 && temp_filename[len-1] != '/')
1363     temp_filename[len++] = '/';
1364   strcpy (temp_filename + len, "ccXXXXXX");
1365
1366   mktemp (temp_filename);
1367   temp_filename_length = strlen (temp_filename);
1368   if (temp_filename_length == 0)
1369     abort ();
1370 }
1371 \f
1372
1373 /* Routine to add variables to the environment.  We do this to pass
1374    the pathname of the gcc driver, and the directories search to the
1375    collect2 program, which is being run as ld.  This way, we can be
1376    sure of executing the right compiler when collect2 wants to build
1377    constructors and destructors.  Since the environment variables we
1378    use come from an obstack, we don't have to worry about allocating
1379    space for them.  */
1380
1381 #ifndef HAVE_PUTENV
1382
1383 void
1384 putenv (str)
1385      char *str;
1386 {
1387 #ifndef VMS                     /* nor about VMS */
1388
1389   extern char **environ;
1390   char **old_environ = environ;
1391   char **envp;
1392   int num_envs = 0;
1393   int name_len = 1;
1394   int str_len = strlen (str);
1395   char *p = str;
1396   int ch;
1397
1398   while ((ch = *p++) != '\0' && ch != '=')
1399     name_len++;
1400
1401   if (!ch)
1402     abort ();
1403
1404   /* Search for replacing an existing environment variable, and
1405      count the number of total environment variables.  */
1406   for (envp = old_environ; *envp; envp++)
1407     {
1408       num_envs++;
1409       if (!strncmp (str, *envp, name_len))
1410         {
1411           *envp = str;
1412           return;
1413         }
1414     }
1415
1416   /* Add a new environment variable */
1417   environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
1418   *environ = str;
1419   bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));
1420
1421 #endif  /* VMS */
1422 }
1423
1424 #endif  /* HAVE_PUTENV */
1425
1426 \f
1427 /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect.  */
1428
1429 static void
1430 putenv_from_prefixes (paths, env_var)
1431      struct path_prefix *paths;
1432      char *env_var;
1433 {
1434   int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
1435   int just_suffix_len
1436     = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
1437   int first_time = TRUE;
1438   struct prefix_list *pprefix;
1439
1440   obstack_grow (&collect_obstack, env_var, strlen (env_var));
1441
1442   for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
1443     {
1444       int len = strlen (pprefix->prefix);
1445
1446       if (machine_suffix
1447           && is_directory (pprefix->prefix, machine_suffix, 0))
1448         {
1449           if (!first_time)
1450             obstack_1grow (&collect_obstack, PATH_SEPARATOR);
1451             
1452           first_time = FALSE;
1453           obstack_grow (&collect_obstack, pprefix->prefix, len);
1454           obstack_grow (&collect_obstack, machine_suffix, suffix_len);
1455         }
1456
1457       if (just_machine_suffix
1458           && pprefix->require_machine_suffix == 2
1459           && is_directory (pprefix->prefix, just_machine_suffix, 0))
1460         {
1461           if (!first_time)
1462             obstack_1grow (&collect_obstack, PATH_SEPARATOR);
1463             
1464           first_time = FALSE;
1465           obstack_grow (&collect_obstack, pprefix->prefix, len);
1466           obstack_grow (&collect_obstack, just_machine_suffix,
1467                         just_suffix_len);
1468         }
1469
1470       if (!pprefix->require_machine_suffix)
1471         {
1472           if (!first_time)
1473             obstack_1grow (&collect_obstack, PATH_SEPARATOR);
1474
1475           first_time = FALSE;
1476           obstack_grow (&collect_obstack, pprefix->prefix, len);
1477         }
1478     }
1479   obstack_1grow (&collect_obstack, '\0');
1480   putenv (obstack_finish (&collect_obstack));
1481 }
1482
1483 \f
1484 /* Search for NAME using the prefix list PREFIXES.  MODE is passed to
1485    access to check permissions.
1486    Return 0 if not found, otherwise return its name, allocated with malloc. */
1487
1488 static char *
1489 find_a_file (pprefix, name, mode)
1490      struct path_prefix *pprefix;
1491      char *name;
1492      int mode;
1493 {
1494   char *temp;
1495   char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : "");
1496   struct prefix_list *pl;
1497   int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
1498
1499   if (machine_suffix)
1500     len += strlen (machine_suffix);
1501
1502   temp = xmalloc (len);
1503
1504   /* Determine the filename to execute (special case for absolute paths).  */
1505
1506   if (*name == '/')
1507     {
1508       if (access (name, mode))
1509         {
1510           strcpy (temp, name);
1511           return temp;
1512         }
1513     }
1514   else
1515     for (pl = pprefix->plist; pl; pl = pl->next)
1516       {
1517         if (machine_suffix)
1518           {
1519             strcpy (temp, pl->prefix);
1520             strcat (temp, machine_suffix);
1521             strcat (temp, name);
1522             if (access (temp, mode) == 0)
1523               {
1524                 if (pl->used_flag_ptr != 0)
1525                   *pl->used_flag_ptr = 1;
1526                 return temp;
1527               }
1528             /* Some systems have a suffix for executable files.
1529                So try appending that.  */
1530             if (file_suffix[0] != 0)
1531               {
1532                 strcat (temp, file_suffix);
1533                 if (access (temp, mode) == 0)
1534                   {
1535                     if (pl->used_flag_ptr != 0)
1536                       *pl->used_flag_ptr = 1;
1537                     return temp;
1538                   }
1539               }
1540           }
1541         /* Certain prefixes are tried with just the machine type,
1542            not the version.  This is used for finding as, ld, etc.  */
1543         if (just_machine_suffix && pl->require_machine_suffix == 2)
1544           {
1545             strcpy (temp, pl->prefix);
1546             strcat (temp, just_machine_suffix);
1547             strcat (temp, name);
1548             if (access (temp, mode) == 0)
1549               {
1550                 if (pl->used_flag_ptr != 0)
1551                   *pl->used_flag_ptr = 1;
1552                 return temp;
1553               }
1554             /* Some systems have a suffix for executable files.
1555                So try appending that.  */
1556             if (file_suffix[0] != 0)
1557               {
1558                 strcat (temp, file_suffix);
1559                 if (access (temp, mode) == 0)
1560                   {
1561                     if (pl->used_flag_ptr != 0)
1562                       *pl->used_flag_ptr = 1;
1563                     return temp;
1564                   }
1565               }
1566           }
1567         /* Certain prefixes can't be used without the machine suffix
1568            when the machine or version is explicitly specified.  */
1569         if (!pl->require_machine_suffix)
1570           {
1571             strcpy (temp, pl->prefix);
1572             strcat (temp, name);
1573             if (access (temp, mode) == 0)
1574               {
1575                 if (pl->used_flag_ptr != 0)
1576                   *pl->used_flag_ptr = 1;
1577                 return temp;
1578               }
1579             /* Some systems have a suffix for executable files.
1580                So try appending that.  */
1581             if (file_suffix[0] != 0)
1582               {
1583                 strcat (temp, file_suffix);
1584                 if (access (temp, mode) == 0)
1585                   {
1586                     if (pl->used_flag_ptr != 0)
1587                       *pl->used_flag_ptr = 1;
1588                     return temp;
1589                   }
1590               }
1591           }
1592       }
1593
1594   free (temp);
1595   return 0;
1596 }
1597
1598 /* Add an entry for PREFIX in PLIST.  If FIRST is set, it goes
1599    at the start of the list, otherwise it goes at the end.
1600
1601    If WARN is nonzero, we will warn if no file is found
1602    through this prefix.  WARN should point to an int
1603    which will be set to 1 if this entry is used.
1604
1605    REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
1606    the complete value of machine_suffix.
1607    2 means try both machine_suffix and just_machine_suffix.  */
1608
1609 static void
1610 add_prefix (pprefix, prefix, first, require_machine_suffix, warn)
1611      struct path_prefix *pprefix;
1612      char *prefix;
1613      int first;
1614      int require_machine_suffix;
1615      int *warn;
1616 {
1617   struct prefix_list *pl, **prev;
1618   int len;
1619
1620   if (!first && pprefix->plist)
1621     {
1622       for (pl = pprefix->plist; pl->next; pl = pl->next)
1623         ;
1624       prev = &pl->next;
1625     }
1626   else
1627     prev = &pprefix->plist;
1628
1629   /* Keep track of the longest prefix */
1630
1631   len = strlen (prefix);
1632   if (len > pprefix->max_len)
1633     pprefix->max_len = len;
1634
1635   pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
1636   pl->prefix = save_string (prefix, len);
1637   pl->require_machine_suffix = require_machine_suffix;
1638   pl->used_flag_ptr = warn;
1639   if (warn)
1640     *warn = 0;
1641
1642   if (*prev)
1643     pl->next = *prev;
1644   else
1645     pl->next = (struct prefix_list *) 0;
1646   *prev = pl;
1647 }
1648
1649 /* Print warnings for any prefixes in the list PPREFIX that were not used.  */
1650
1651 static void
1652 unused_prefix_warnings (pprefix)
1653      struct path_prefix *pprefix;
1654 {
1655   struct prefix_list *pl = pprefix->plist;
1656
1657   while (pl)
1658     {
1659       if (pl->used_flag_ptr != 0 && !*pl->used_flag_ptr)
1660         {
1661           error ("file path prefix `%s' never used",
1662                  pl->prefix);
1663           /* Prevent duplicate warnings.  */
1664           *pl->used_flag_ptr = 1;
1665         }
1666       pl = pl->next;
1667     }
1668 }
1669
1670 /* Get rid of all prefixes built up so far in *PLISTP. */
1671
1672 static void
1673 free_path_prefix (pprefix)
1674      struct path_prefix *pprefix;
1675 {
1676   struct prefix_list *pl = pprefix->plist;
1677   struct prefix_list *temp;
1678
1679   while (pl)
1680     {
1681       temp = pl;
1682       pl = pl->next;
1683       free (temp->prefix);
1684       free ((char *) temp);
1685     }
1686   pprefix->plist = (struct prefix_list *) 0;
1687 }
1688 \f
1689 /* stdin file number.  */
1690 #define STDIN_FILE_NO 0
1691
1692 /* stdout file number.  */
1693 #define STDOUT_FILE_NO 1
1694
1695 /* value of `pipe': port index for reading.  */
1696 #define READ_PORT 0
1697
1698 /* value of `pipe': port index for writing.  */
1699 #define WRITE_PORT 1
1700
1701 /* Pipe waiting from last process, to be used as input for the next one.
1702    Value is STDIN_FILE_NO if no pipe is waiting
1703    (i.e. the next command is the first of a group).  */
1704
1705 static int last_pipe_input;
1706
1707 /* Fork one piped subcommand.  FUNC is the system call to use
1708    (either execv or execvp).  ARGV is the arg vector to use.
1709    NOT_LAST is nonzero if this is not the last subcommand
1710    (i.e. its output should be piped to the next one.)  */
1711
1712 #ifndef OS2
1713 #ifdef __MSDOS__
1714
1715 /* Declare these to avoid compilation error.  They won't be called.  */
1716 int execv(const char *a, const char **b){}
1717 int execvp(const char *a, const char **b){}
1718
1719 static int
1720 pexecute (search_flag, program, argv, not_last)
1721      int search_flag;
1722      char *program;
1723      char *argv[];
1724      int not_last;
1725 {
1726   char *scmd;
1727   FILE *argfile;
1728   int i;
1729
1730   scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 6);
1731   sprintf (scmd, "%s @%s.gp", program, temp_filename);
1732   argfile = fopen (scmd+strlen (program) + 2, "w");
1733   if (argfile == 0)
1734     pfatal_with_name (scmd + strlen (program) + 2);
1735
1736   for (i=1; argv[i]; i++)
1737   {
1738     char *cp;
1739     for (cp = argv[i]; *cp; cp++)
1740       {
1741         if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
1742           fputc ('\\', argfile);
1743         fputc (*cp, argfile);
1744       }
1745     fputc ('\n', argfile);
1746   }
1747   fclose (argfile);
1748
1749   i = system (scmd);
1750
1751   remove (scmd + strlen (program) + 2);
1752   return i << 8;
1753 }
1754
1755 #else /* not __MSDOS__ */
1756
1757 static int
1758 pexecute (search_flag, program, argv, not_last)
1759      int search_flag;
1760      char *program;
1761      char *argv[];
1762      int not_last;
1763 {
1764   int (*func)() = (search_flag ? execv : execvp);
1765   int pid;
1766   int pdes[2];
1767   int input_desc = last_pipe_input;
1768   int output_desc = STDOUT_FILE_NO;
1769   int retries, sleep_interval;
1770
1771   /* If this isn't the last process, make a pipe for its output,
1772      and record it as waiting to be the input to the next process.  */
1773
1774   if (not_last)
1775     {
1776       if (pipe (pdes) < 0)
1777         pfatal_with_name ("pipe");
1778       output_desc = pdes[WRITE_PORT];
1779       last_pipe_input = pdes[READ_PORT];
1780     }
1781   else
1782     last_pipe_input = STDIN_FILE_NO;
1783
1784   /* Fork a subprocess; wait and retry if it fails.  */
1785   sleep_interval = 1;
1786   for (retries = 0; retries < 4; retries++)
1787     {
1788       pid = vfork ();
1789       if (pid >= 0)
1790         break;
1791       sleep (sleep_interval);
1792       sleep_interval *= 2;
1793     }
1794
1795   switch (pid)
1796     {
1797     case -1:
1798 #ifdef vfork
1799       pfatal_with_name ("fork");
1800 #else
1801       pfatal_with_name ("vfork");
1802 #endif
1803       /* NOTREACHED */
1804       return 0;
1805
1806     case 0: /* child */
1807       /* Move the input and output pipes into place, if nec.  */
1808       if (input_desc != STDIN_FILE_NO)
1809         {
1810           close (STDIN_FILE_NO);
1811           dup (input_desc);
1812           close (input_desc);
1813         }
1814       if (output_desc != STDOUT_FILE_NO)
1815         {
1816           close (STDOUT_FILE_NO);
1817           dup (output_desc);
1818           close (output_desc);
1819         }
1820
1821       /* Close the parent's descs that aren't wanted here.  */
1822       if (last_pipe_input != STDIN_FILE_NO)
1823         close (last_pipe_input);
1824
1825       /* Exec the program.  */
1826       (*func) (program, argv);
1827       perror_exec (program);
1828       exit (-1);
1829       /* NOTREACHED */
1830       return 0;
1831
1832     default:
1833       /* In the parent, after forking.
1834          Close the descriptors that we made for this child.  */
1835       if (input_desc != STDIN_FILE_NO)
1836         close (input_desc);
1837       if (output_desc != STDOUT_FILE_NO)
1838         close (output_desc);
1839
1840       /* Return child's process number.  */
1841       return pid;
1842     }
1843 }
1844
1845 #endif /* not __MSDOS__ */
1846 #else /* not OS2 */
1847
1848 static int
1849 pexecute (search_flag, program, argv, not_last)
1850      int search_flag;
1851      char *program;
1852      char *argv[];
1853      int not_last;
1854 {
1855   return (search_flag ? spawnv : spawnvp) (1, program, argv);
1856 }
1857 #endif /* not OS2 */
1858 \f
1859 /* Execute the command specified by the arguments on the current line of spec.
1860    When using pipes, this includes several piped-together commands
1861    with `|' between them.
1862
1863    Return 0 if successful, -1 if failed.  */
1864
1865 static int
1866 execute ()
1867 {
1868   int i;
1869   int n_commands;               /* # of command.  */
1870   char *string;
1871   struct command
1872     {
1873       char *prog;               /* program name.  */
1874       char **argv;              /* vector of args.  */
1875       int pid;                  /* pid of process for this command.  */
1876     };
1877
1878   struct command *commands;     /* each command buffer with above info.  */
1879
1880   /* Count # of piped commands.  */
1881   for (n_commands = 1, i = 0; i < argbuf_index; i++)
1882     if (strcmp (argbuf[i], "|") == 0)
1883       n_commands++;
1884
1885   /* Get storage for each command.  */
1886   commands
1887     = (struct command *) alloca (n_commands * sizeof (struct command));
1888
1889   /* Split argbuf into its separate piped processes,
1890      and record info about each one.
1891      Also search for the programs that are to be run.  */
1892
1893   commands[0].prog = argbuf[0]; /* first command.  */
1894   commands[0].argv = &argbuf[0];
1895   string = find_a_file (&exec_prefix, commands[0].prog, X_OK);
1896   if (string)
1897     commands[0].argv[0] = string;
1898
1899   for (n_commands = 1, i = 0; i < argbuf_index; i++)
1900     if (strcmp (argbuf[i], "|") == 0)
1901       {                         /* each command.  */
1902 #ifdef __MSDOS__
1903         fatal ("-pipe not supported under MS-DOS");
1904 #endif
1905         argbuf[i] = 0;  /* termination of command args.  */
1906         commands[n_commands].prog = argbuf[i + 1];
1907         commands[n_commands].argv = &argbuf[i + 1];
1908         string = find_a_file (&exec_prefix, commands[n_commands].prog, X_OK);
1909         if (string)
1910           commands[n_commands].argv[0] = string;
1911         n_commands++;
1912       }
1913
1914   argbuf[argbuf_index] = 0;
1915
1916   /* If -v, print what we are about to do, and maybe query.  */
1917
1918   if (verbose_flag)
1919     {
1920       /* Print each piped command as a separate line.  */
1921       for (i = 0; i < n_commands ; i++)
1922         {
1923           char **j;
1924
1925           for (j = commands[i].argv; *j; j++)
1926             fprintf (stderr, " %s", *j);
1927
1928           /* Print a pipe symbol after all but the last command.  */
1929           if (i + 1 != n_commands)
1930             fprintf (stderr, " |");
1931           fprintf (stderr, "\n");
1932         }
1933       fflush (stderr);
1934 #ifdef DEBUG
1935       fprintf (stderr, "\nGo ahead? (y or n) ");
1936       fflush (stderr);
1937       i = getchar ();
1938       if (i != '\n')
1939         while (getchar () != '\n') ;
1940       if (i != 'y' && i != 'Y')
1941         return 0;
1942 #endif /* DEBUG */
1943     }
1944
1945   /* Run each piped subprocess.  */
1946
1947   last_pipe_input = STDIN_FILE_NO;
1948   for (i = 0; i < n_commands; i++)
1949     {
1950       char *string = commands[i].argv[0];
1951
1952       commands[i].pid = pexecute (string != commands[i].prog,
1953                                   string, commands[i].argv,
1954                                   i + 1 < n_commands);
1955
1956       if (string != commands[i].prog)
1957         free (string);
1958     }
1959
1960   execution_count++;
1961
1962   /* Wait for all the subprocesses to finish.
1963      We don't care what order they finish in;
1964      we know that N_COMMANDS waits will get them all.  */
1965
1966   {
1967     int ret_code = 0;
1968
1969     for (i = 0; i < n_commands; i++)
1970       {
1971         int status;
1972         int pid;
1973         char *prog;
1974
1975 #ifdef __MSDOS__
1976         status = pid = commands[i].pid;
1977 #else
1978         pid = wait (&status);
1979 #endif
1980         if (pid < 0)
1981           abort ();
1982
1983         if (status != 0)
1984           {
1985             int j;
1986             for (j = 0; j < n_commands; j++)
1987               if (commands[j].pid == pid)
1988                 prog = commands[j].prog;
1989
1990             if ((status & 0x7F) != 0)
1991               {
1992                 fatal ("Internal compiler error: program %s got fatal signal %d",
1993                        prog, (status & 0x7F));
1994                 signal_count++;
1995               }
1996             if (((status & 0xFF00) >> 8) >= MIN_FATAL_STATUS)
1997               ret_code = -1;
1998           }
1999       }
2000     return ret_code;
2001   }
2002 }
2003 \f
2004 /* Find all the switches given to us
2005    and make a vector describing them.
2006    The elements of the vector are strings, one per switch given.
2007    If a switch uses following arguments, then the `part1' field
2008    is the switch itself and the `args' field
2009    is a null-terminated vector containing the following arguments.
2010    The `valid' field is nonzero if any spec has looked at this switch;
2011    if it remains zero at the end of the run, it must be meaningless.  */
2012
2013 struct switchstr
2014 {
2015   char *part1;
2016   char **args;
2017   int valid;
2018 };
2019
2020 static struct switchstr *switches;
2021
2022 static int n_switches;
2023
2024 struct infile
2025 {
2026   char *name;
2027   char *language;
2028 };
2029
2030 /* Also a vector of input files specified.  */
2031
2032 static struct infile *infiles;
2033
2034 static int n_infiles;
2035
2036 /* And a vector of corresponding output files is made up later.  */
2037
2038 static char **outfiles;
2039
2040 /* Create the vector `switches' and its contents.
2041    Store its length in `n_switches'.  */
2042
2043 static void
2044 process_command (argc, argv)
2045      int argc;
2046      char **argv;
2047 {
2048   register int i;
2049   char *temp;
2050   char *spec_lang = 0;
2051   int last_language_n_infiles;
2052
2053   gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX");
2054
2055   n_switches = 0;
2056   n_infiles = 0;
2057
2058   /* Default for -V is our version number, ending at first space.  */
2059   spec_version = save_string (version_string, strlen (version_string));
2060   for (temp = spec_version; *temp && *temp != ' '; temp++);
2061   if (*temp) *temp = '\0';
2062
2063   /* Set up the default search paths.  */
2064
2065   if (gcc_exec_prefix)
2066     {
2067       add_prefix (&exec_prefix, gcc_exec_prefix, 0, 0, NULL_PTR);
2068       add_prefix (&startfile_prefix, gcc_exec_prefix, 0, 0, NULL_PTR);
2069     }
2070
2071   /* COMPILER_PATH and LIBRARY_PATH have values
2072      that are lists of directory names with colons.  */
2073
2074   temp = getenv ("COMPILER_PATH");
2075   if (temp)
2076     {
2077       char *startp, *endp;
2078       char *nstore = (char *) alloca (strlen (temp) + 3);
2079
2080       startp = endp = temp;
2081       while (1)
2082         {
2083           if (*endp == PATH_SEPARATOR || *endp == 0)
2084             {
2085               strncpy (nstore, startp, endp-startp);
2086               if (endp == startp)
2087                 {
2088                   strcpy (nstore, "./");
2089                 }
2090               else if (endp[-1] != '/')
2091                 {
2092                   nstore[endp-startp] = '/';
2093                   nstore[endp-startp+1] = 0;
2094                 }
2095               else
2096                 nstore[endp-startp] = 0;
2097               add_prefix (&exec_prefix, nstore, 0, 0, NULL_PTR);
2098               if (*endp == 0)
2099                 break;
2100               endp = startp = endp + 1;
2101             }
2102           else
2103             endp++;
2104         }
2105     }
2106
2107   temp = getenv ("LIBRARY_PATH");
2108   if (temp)
2109     {
2110       char *startp, *endp;
2111       char *nstore = (char *) alloca (strlen (temp) + 3);
2112
2113       startp = endp = temp;
2114       while (1)
2115         {
2116           if (*endp == PATH_SEPARATOR || *endp == 0)
2117             {
2118               strncpy (nstore, startp, endp-startp);
2119               if (endp == startp)
2120                 {
2121                   strcpy (nstore, "./");
2122                 }
2123               else if (endp[-1] != '/')
2124                 {
2125                   nstore[endp-startp] = '/';
2126                   nstore[endp-startp+1] = 0;
2127                 }
2128               else
2129                 nstore[endp-startp] = 0;
2130               add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR);
2131               if (*endp == 0)
2132                 break;
2133               endp = startp = endp + 1;
2134             }
2135           else
2136             endp++;
2137         }
2138     }
2139
2140   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
2141   temp = getenv ("LPATH");
2142   if (temp)
2143     {
2144       char *startp, *endp;
2145       char *nstore = (char *) alloca (strlen (temp) + 3);
2146
2147       startp = endp = temp;
2148       while (1)
2149         {
2150           if (*endp == PATH_SEPARATOR || *endp == 0)
2151             {
2152               strncpy (nstore, startp, endp-startp);
2153               if (endp == startp)
2154                 {
2155                   strcpy (nstore, "./");
2156                 }
2157               else if (endp[-1] != '/')
2158                 {
2159                   nstore[endp-startp] = '/';
2160                   nstore[endp-startp+1] = 0;
2161                 }
2162               else
2163                 nstore[endp-startp] = 0;
2164               add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR);
2165               if (*endp == 0)
2166                 break;
2167               endp = startp = endp + 1;
2168             }
2169           else
2170             endp++;
2171         }
2172     }
2173
2174   /* Convert new-style -- options to old-style.  */
2175   translate_options (&argc, &argv);
2176
2177   /* Scan argv twice.  Here, the first time, just count how many switches
2178      there will be in their vector, and how many input files in theirs.
2179      Here we also parse the switches that cc itself uses (e.g. -v).  */
2180
2181   for (i = 1; i < argc; i++)
2182     {
2183       if (! strcmp (argv[i], "-dumpspecs"))
2184         {
2185           printf ("*asm:\n%s\n\n", asm_spec);
2186           printf ("*asm_final:\n%s\n\n", asm_final_spec);
2187           printf ("*cpp:\n%s\n\n", cpp_spec);
2188           printf ("*cc1:\n%s\n\n", cc1_spec);
2189           printf ("*cc1plus:\n%s\n\n", cc1plus_spec);
2190           printf ("*endfile:\n%s\n\n", endfile_spec);
2191           printf ("*link:\n%s\n\n", link_spec);
2192           printf ("*lib:\n%s\n\n", lib_spec);
2193           printf ("*startfile:\n%s\n\n", startfile_spec);
2194           printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces);
2195           printf ("*signed_char:\n%s\n\n", signed_char_spec);
2196           printf ("*predefines:\n%s\n\n", cpp_predefines);
2197           printf ("*cross_compile:\n%d\n\n", cross_compile);
2198
2199           exit (0);
2200         }
2201       else if (! strcmp (argv[i], "-dumpversion"))
2202         {
2203           printf ("%s\n", version_string);
2204           exit (0);
2205         }
2206       else if (! strcmp (argv[i], "-print-libgcc-file-name"))
2207         {
2208           print_libgcc_file_name = 1;
2209         }
2210       else if (! strcmp (argv[i], "-Xlinker"))
2211         {
2212           /* Pass the argument of this option to the linker when we link.  */
2213
2214           if (i + 1 == argc)
2215             fatal ("argument to `-Xlinker' is missing");
2216
2217           n_linker_options++;
2218           if (!linker_options)
2219             linker_options
2220               = (char **) xmalloc (n_linker_options * sizeof (char **));
2221           else
2222             linker_options
2223               = (char **) xrealloc (linker_options,
2224                                     n_linker_options * sizeof (char **));
2225
2226           linker_options[n_linker_options - 1] = argv[++i];
2227         }
2228       else if (! strncmp (argv[i], "-Wl,", 4))
2229         {
2230           int prev, j;
2231           /* Pass the rest of this option to the linker when we link.  */
2232
2233           n_linker_options++;
2234           if (!linker_options)
2235             linker_options
2236               = (char **) xmalloc (n_linker_options * sizeof (char **));
2237           else
2238             linker_options
2239               = (char **) xrealloc (linker_options,
2240                                     n_linker_options * sizeof (char **));
2241
2242           /* Split the argument at commas.  */
2243           prev = 4;
2244           for (j = 4; argv[i][j]; j++)
2245             if (argv[i][j] == ',')
2246               {
2247                 linker_options[n_linker_options - 1]
2248                   = save_string (argv[i] + prev, j - prev);
2249                 n_linker_options++;
2250                 linker_options
2251                   = (char **) xrealloc (linker_options,
2252                                         n_linker_options * sizeof (char **));
2253                 prev = j + 1;
2254               }
2255           /* Record the part after the last comma.  */
2256           linker_options[n_linker_options - 1] = argv[i] + prev;
2257         }
2258       else if (! strncmp (argv[i], "-Wa,", 4))
2259         {
2260           int prev, j;
2261           /* Pass the rest of this option to the assembler.  */
2262
2263           n_assembler_options++;
2264           if (!assembler_options)
2265             assembler_options
2266               = (char **) xmalloc (n_assembler_options * sizeof (char **));
2267           else
2268             assembler_options
2269               = (char **) xrealloc (assembler_options,
2270                                     n_assembler_options * sizeof (char **));
2271
2272           /* Split the argument at commas.  */
2273           prev = 4;
2274           for (j = 4; argv[i][j]; j++)
2275             if (argv[i][j] == ',')
2276               {
2277                 assembler_options[n_assembler_options - 1]
2278                   = save_string (argv[i] + prev, j - prev);
2279                 n_assembler_options++;
2280                 assembler_options
2281                   = (char **) xrealloc (assembler_options,
2282                                         n_assembler_options * sizeof (char **));
2283                 prev = j + 1;
2284               }
2285           /* Record the part after the last comma.  */
2286           assembler_options[n_assembler_options - 1] = argv[i] + prev;
2287         }
2288       else if (argv[i][0] == '+' && argv[i][1] == 'e')
2289         /* The +e options to the C++ front-end.  */
2290         n_switches++;
2291       else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l')
2292         {
2293           register char *p = &argv[i][1];
2294           register int c = *p;
2295
2296           switch (c)
2297             {
2298             case 'b':
2299               if (p[1] == 0 && i + 1 == argc)
2300                 fatal ("argument to `-b' is missing");
2301               if (p[1] == 0)
2302                 spec_machine = argv[++i];
2303               else
2304                 spec_machine = p + 1;
2305               break;
2306
2307             case 'B':
2308               {
2309                 int *temp = (int *) xmalloc (sizeof (int));
2310                 char *value;
2311                 if (p[1] == 0 && i + 1 == argc)
2312                   fatal ("argument to `-B' is missing");
2313                 if (p[1] == 0)
2314                   value = argv[++i];
2315                 else
2316                   value = p + 1;
2317                 add_prefix (&exec_prefix, value, 1, 0, temp);
2318                 add_prefix (&startfile_prefix, value, 1, 0, temp);
2319               }
2320               break;
2321
2322             case 'v':   /* Print our subcommands and print versions.  */
2323               n_switches++;
2324               /* If they do anything other than exactly `-v', don't set
2325                  verbose_flag; rather, continue on to give the error.  */
2326               if (p[1] != 0)
2327                 break;
2328               verbose_flag++;
2329               break;
2330
2331             case 'V':
2332               if (p[1] == 0 && i + 1 == argc)
2333                 fatal ("argument to `-V' is missing");
2334               if (p[1] == 0)
2335                 spec_version = argv[++i];
2336               else
2337                 spec_version = p + 1;
2338               break;
2339
2340             case 's':
2341               if (!strcmp (p, "save-temps"))
2342                 {
2343                   save_temps_flag = 1;
2344                   n_switches++;
2345                   break;
2346                 }
2347             default:
2348               n_switches++;
2349
2350               if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
2351                 i += SWITCH_TAKES_ARG (c) - (p[1] != 0);
2352               else if (WORD_SWITCH_TAKES_ARG (p))
2353                 i += WORD_SWITCH_TAKES_ARG (p);
2354             }
2355         }
2356       else
2357         n_infiles++;
2358     }
2359
2360   /* Set up the search paths before we go looking for config files.  */
2361
2362   /* These come before the md prefixes so that we will find gcc's subcommands
2363      (such as cpp) rather than those of the host system.  */
2364   /* Use 2 as fourth arg meaning try just the machine as a suffix,
2365      as well as trying the machine and the version.  */
2366   add_prefix (&exec_prefix, standard_exec_prefix, 0, 2, NULL_PTR);
2367   add_prefix (&exec_prefix, standard_exec_prefix_1, 0, 2, NULL_PTR);
2368
2369   add_prefix (&startfile_prefix, standard_exec_prefix, 0, 1, NULL_PTR);
2370   add_prefix (&startfile_prefix, standard_exec_prefix_1, 0, 1, NULL_PTR);
2371
2372   tooldir_prefix = concat (tooldir_base_prefix, spec_machine, "/");
2373
2374   /* If tooldir is relative, base it on exec_prefix.  A relative
2375      tooldir lets us move the installed tree as a unit.
2376
2377      If GCC_EXEC_PREFIX is defined, then we want to add two relative
2378      directories, so that we can search both the user specified directory
2379      and the standard place.  */
2380
2381   if (*tooldir_prefix != '/')
2382     {
2383       if (gcc_exec_prefix)
2384         {
2385           char *gcc_exec_tooldir_prefix
2386             = concat (concat (gcc_exec_prefix, spec_machine, "/"),
2387                       concat (spec_version, "/", tooldir_prefix),
2388                       "");
2389
2390           add_prefix (&exec_prefix, concat (gcc_exec_tooldir_prefix, "bin", "/"),
2391                       0, 0, NULL_PTR);
2392           add_prefix (&startfile_prefix, concat (gcc_exec_tooldir_prefix, "lib", "/"),
2393                       0, 0, NULL_PTR);
2394         }
2395
2396       tooldir_prefix = concat (concat (standard_exec_prefix, spec_machine, "/"),
2397                                concat (spec_version, "/", tooldir_prefix),
2398                                "");
2399     }
2400
2401   add_prefix (&exec_prefix, concat (tooldir_prefix, "bin", "/"),
2402               0, 0, NULL_PTR);
2403   add_prefix (&startfile_prefix, concat (tooldir_prefix, "lib", "/"),
2404               0, 0, NULL_PTR);
2405
2406   /* More prefixes are enabled in main, after we read the specs file
2407      and determine whether this is cross-compilation or not.  */
2408
2409
2410   /* Then create the space for the vectors and scan again.  */
2411
2412   switches = ((struct switchstr *)
2413               xmalloc ((n_switches + 1) * sizeof (struct switchstr)));
2414   infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile));
2415   n_switches = 0;
2416   n_infiles = 0;
2417   last_language_n_infiles = -1;
2418
2419   /* This, time, copy the text of each switch and store a pointer
2420      to the copy in the vector of switches.
2421      Store all the infiles in their vector.  */
2422
2423   for (i = 1; i < argc; i++)
2424     {
2425       /* Just skip the switches that were handled by the preceding loop.  */
2426       if (!strcmp (argv[i], "-Xlinker"))
2427         i++;
2428       else if (! strncmp (argv[i], "-Wl,", 4))
2429         ;
2430       else if (! strncmp (argv[i], "-Wa,", 4))
2431         ;
2432       else if (! strcmp (argv[i], "-print-libgcc-file-name"))
2433         ;
2434       else if (argv[i][0] == '+' && argv[i][1] == 'e')
2435         {
2436           /* Compensate for the +e options to the C++ front-end;
2437              they're there simply for cfront call-compatibility.  We do
2438              some magic in default_compilers to pass them down properly.
2439              Note we deliberately start at the `+' here, to avoid passing
2440              -e0 or -e1 down into the linker.  */
2441           switches[n_switches].part1 = &argv[i][0];
2442           switches[n_switches].args = 0;
2443           switches[n_switches].valid = 0;
2444           n_switches++;
2445         }
2446       else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l')
2447         {
2448           register char *p = &argv[i][1];
2449           register int c = *p;
2450
2451           if (c == 'B' || c == 'b' || c == 'V')
2452             {
2453               /* Skip a separate arg, if any.  */
2454               if (p[1] == 0)
2455                 i++;
2456               continue;
2457             }
2458           if (c == 'x')
2459             {
2460               if (p[1] == 0 && i + 1 == argc)
2461                 fatal ("argument to `-x' is missing");
2462               if (p[1] == 0)
2463                 spec_lang = argv[++i];
2464               else
2465                 spec_lang = p + 1;
2466               if (! strcmp (spec_lang, "none"))
2467                 /* Suppress the warning if -xnone comes after the last input file,
2468                    because alternate command interfaces like g++ might find it
2469                    useful to place -xnone after each input file.  */
2470                 spec_lang = 0;
2471               else
2472                 last_language_n_infiles = n_infiles;
2473               continue;
2474             }
2475           switches[n_switches].part1 = p;
2476           /* Deal with option arguments in separate argv elements.  */
2477           if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
2478               || WORD_SWITCH_TAKES_ARG (p)) {
2479             int j = 0;
2480             int n_args = WORD_SWITCH_TAKES_ARG (p);
2481
2482             if (n_args == 0) {
2483               /* Count only the option arguments in separate argv elements.  */
2484               n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
2485             }
2486             if (i + n_args >= argc)
2487               fatal ("argument to `-%s' is missing", p);
2488             switches[n_switches].args
2489               = (char **) xmalloc ((n_args + 1) * sizeof (char *));
2490             while (j < n_args)
2491               switches[n_switches].args[j++] = argv[++i];
2492             /* Null-terminate the vector.  */
2493             switches[n_switches].args[j] = 0;
2494           } else if (*switches_need_spaces != 0 && (c == 'o' || c == 'L')) {
2495             /* On some systems, ld cannot handle -o or -L without space.
2496                So split the -o or -L from its argument.  */
2497             switches[n_switches].part1 = (c == 'o' ? "o" : "L");
2498             switches[n_switches].args = (char **) xmalloc (2 * sizeof (char *));
2499             switches[n_switches].args[0] = xmalloc (strlen (p));
2500             strcpy (switches[n_switches].args[0], &p[1]);
2501             switches[n_switches].args[1] = 0;
2502           } else
2503             switches[n_switches].args = 0;
2504           switches[n_switches].valid = 0;
2505           /* This is always valid, since gcc.c itself understands it.  */
2506           if (!strcmp (p, "save-temps"))
2507             switches[n_switches].valid = 1;
2508           n_switches++;
2509         }
2510       else
2511         {
2512           if ((argv[i][0] != '-' || argv[i][1] != 'l')
2513               && access (argv[i], R_OK) < 0)
2514             {
2515               perror_with_name (argv[i]);
2516               error_count++;
2517             }
2518           else
2519             {
2520               infiles[n_infiles].language = spec_lang;
2521               infiles[n_infiles++].name = argv[i];
2522             }
2523         }
2524     }
2525
2526   if (n_infiles == last_language_n_infiles)
2527     error ("Warning: `-x %s' after last input file has no effect", spec_lang);
2528
2529   switches[n_switches].part1 = 0;
2530   infiles[n_infiles].name = 0;
2531
2532   /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
2533   if (gcc_exec_prefix)
2534     {
2535       temp = (char *) xmalloc (strlen (gcc_exec_prefix) + strlen (spec_version)
2536                                + strlen (spec_machine) + 3);
2537       strcpy (temp, gcc_exec_prefix);
2538       strcat (temp, spec_machine);
2539       strcat (temp, "/");
2540       strcat (temp, spec_version);
2541       strcat (temp, "/");
2542       gcc_exec_prefix = temp;
2543     }
2544 }
2545 \f
2546 /* Process a spec string, accumulating and running commands.  */
2547
2548 /* These variables describe the input file name.
2549    input_file_number is the index on outfiles of this file,
2550    so that the output file name can be stored for later use by %o.
2551    input_basename is the start of the part of the input file
2552    sans all directory names, and basename_length is the number
2553    of characters starting there excluding the suffix .c or whatever.  */
2554
2555 static char *input_filename;
2556 static int input_file_number;
2557 static int input_filename_length;
2558 static int basename_length;
2559 static char *input_basename;
2560 static char *input_suffix;
2561
2562 /* These are variables used within do_spec and do_spec_1.  */
2563
2564 /* Nonzero if an arg has been started and not yet terminated
2565    (with space, tab or newline).  */
2566 static int arg_going;
2567
2568 /* Nonzero means %d or %g has been seen; the next arg to be terminated
2569    is a temporary file name.  */
2570 static int delete_this_arg;
2571
2572 /* Nonzero means %w has been seen; the next arg to be terminated
2573    is the output file name of this compilation.  */
2574 static int this_is_output_file;
2575
2576 /* Nonzero means %s has been seen; the next arg to be terminated
2577    is the name of a library file and we should try the standard
2578    search dirs for it.  */
2579 static int this_is_library_file;
2580
2581 /* Nonzero means that the input of this command is coming from a pipe.  */
2582 static int input_from_pipe;
2583
2584 /* Process the spec SPEC and run the commands specified therein.
2585    Returns 0 if the spec is successfully processed; -1 if failed.  */
2586
2587 static int
2588 do_spec (spec)
2589      char *spec;
2590 {
2591   int value;
2592
2593   clear_args ();
2594   arg_going = 0;
2595   delete_this_arg = 0;
2596   this_is_output_file = 0;
2597   this_is_library_file = 0;
2598   input_from_pipe = 0;
2599
2600   value = do_spec_1 (spec, 0, NULL_PTR);
2601
2602   /* Force out any unfinished command.
2603      If -pipe, this forces out the last command if it ended in `|'.  */
2604   if (value == 0)
2605     {
2606       if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
2607         argbuf_index--;
2608
2609       if (argbuf_index > 0)
2610         value = execute ();
2611     }
2612
2613   return value;
2614 }
2615
2616 /* Process the sub-spec SPEC as a portion of a larger spec.
2617    This is like processing a whole spec except that we do
2618    not initialize at the beginning and we do not supply a
2619    newline by default at the end.
2620    INSWITCH nonzero means don't process %-sequences in SPEC;
2621    in this case, % is treated as an ordinary character.
2622    This is used while substituting switches.
2623    INSWITCH nonzero also causes SPC not to terminate an argument.
2624
2625    Value is zero unless a line was finished
2626    and the command on that line reported an error.  */
2627
2628 static int
2629 do_spec_1 (spec, inswitch, soft_matched_part)
2630      char *spec;
2631      int inswitch;
2632      char *soft_matched_part;
2633 {
2634   register char *p = spec;
2635   register int c;
2636   int i;
2637   char *string;
2638   int value;
2639
2640   while (c = *p++)
2641     /* If substituting a switch, treat all chars like letters.
2642        Otherwise, NL, SPC, TAB and % are special.  */
2643     switch (inswitch ? 'a' : c)
2644       {
2645       case '\n':
2646         /* End of line: finish any pending argument,
2647            then run the pending command if one has been started.  */
2648         if (arg_going)
2649           {
2650             obstack_1grow (&obstack, 0);
2651             string = obstack_finish (&obstack);
2652             if (this_is_library_file)
2653               string = find_file (string);
2654             store_arg (string, delete_this_arg, this_is_output_file);
2655             if (this_is_output_file)
2656               outfiles[input_file_number] = string;
2657           }
2658         arg_going = 0;
2659
2660         if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
2661           {
2662             int i;
2663             for (i = 0; i < n_switches; i++)
2664               if (!strcmp (switches[i].part1, "pipe"))
2665                 break;
2666
2667             /* A `|' before the newline means use a pipe here,
2668                but only if -pipe was specified.
2669                Otherwise, execute now and don't pass the `|' as an arg.  */
2670             if (i < n_switches)
2671               {
2672                 input_from_pipe = 1;
2673                 switches[i].valid = 1;
2674                 break;
2675               }
2676             else
2677               argbuf_index--;
2678           }
2679
2680         if (argbuf_index > 0)
2681           {
2682             value = execute ();
2683             if (value)
2684               return value;
2685           }
2686         /* Reinitialize for a new command, and for a new argument.  */
2687         clear_args ();
2688         arg_going = 0;
2689         delete_this_arg = 0;
2690         this_is_output_file = 0;
2691         this_is_library_file = 0;
2692         input_from_pipe = 0;
2693         break;
2694
2695       case '|':
2696         /* End any pending argument.  */
2697         if (arg_going)
2698           {
2699             obstack_1grow (&obstack, 0);
2700             string = obstack_finish (&obstack);
2701             if (this_is_library_file)
2702               string = find_file (string);
2703             store_arg (string, delete_this_arg, this_is_output_file);
2704             if (this_is_output_file)
2705               outfiles[input_file_number] = string;
2706           }
2707
2708         /* Use pipe */
2709         obstack_1grow (&obstack, c);
2710         arg_going = 1;
2711         break;
2712
2713       case '\t':
2714       case ' ':
2715         /* Space or tab ends an argument if one is pending.  */
2716         if (arg_going)
2717           {
2718             obstack_1grow (&obstack, 0);
2719             string = obstack_finish (&obstack);
2720             if (this_is_library_file)
2721               string = find_file (string);
2722             store_arg (string, delete_this_arg, this_is_output_file);
2723             if (this_is_output_file)
2724               outfiles[input_file_number] = string;
2725           }
2726         /* Reinitialize for a new argument.  */
2727         arg_going = 0;
2728         delete_this_arg = 0;
2729         this_is_output_file = 0;
2730         this_is_library_file = 0;
2731         break;
2732
2733       case '%':
2734         switch (c = *p++)
2735           {
2736           case 0:
2737             fatal ("Invalid specification!  Bug in cc.");
2738
2739           case 'b':
2740             obstack_grow (&obstack, input_basename, basename_length);
2741             arg_going = 1;
2742             break;
2743
2744           case 'd':
2745             delete_this_arg = 2;
2746             break;
2747
2748           /* Dump out the directories specified with LIBRARY_PATH,
2749              followed by the absolute directories
2750              that we search for startfiles.  */
2751           case 'D':
2752             {
2753               struct prefix_list *pl = startfile_prefix.plist;
2754               int bufsize = 100;
2755               char *buffer = (char *) xmalloc (bufsize);
2756               int idx;
2757
2758               for (; pl; pl = pl->next)
2759                 {
2760 #ifdef RELATIVE_PREFIX_NOT_LINKDIR
2761                   /* Used on systems which record the specified -L dirs
2762                      and use them to search for dynamic linking.  */
2763                   /* Relative directories always come from -B,
2764                      and it is better not to use them for searching
2765                      at run time.  In particular, stage1 loses  */
2766                   if (pl->prefix[0] != '/')
2767                     continue;
2768 #endif
2769                   if (machine_suffix)
2770                     {
2771                       if (is_directory (pl->prefix, machine_suffix, 1))
2772                         {
2773                           do_spec_1 ("-L", 0, NULL_PTR);
2774 #ifdef SPACE_AFTER_L_OPTION
2775                           do_spec_1 (" ", 0, NULL_PTR);
2776 #endif
2777                           do_spec_1 (pl->prefix, 1, NULL_PTR);
2778                           /* Remove slash from machine_suffix.  */
2779                           if (strlen (machine_suffix) >= bufsize)
2780                             bufsize = strlen (machine_suffix) * 2 + 1;
2781                           buffer = (char *) xrealloc (buffer, bufsize);
2782                           strcpy (buffer, machine_suffix);
2783                           idx = strlen (buffer);
2784                           if (buffer[idx - 1] == '/')
2785                             buffer[idx - 1] = 0;
2786                           do_spec_1 (buffer, 1, NULL_PTR);
2787                           /* Make this a separate argument.  */
2788                           do_spec_1 (" ", 0, NULL_PTR);
2789                         }
2790                     }
2791                   if (!pl->require_machine_suffix)
2792                     {
2793                       if (is_directory (pl->prefix, "", 1))
2794                         {
2795                           do_spec_1 ("-L", 0, NULL_PTR);
2796 #ifdef SPACE_AFTER_L_OPTION
2797                           do_spec_1 (" ", 0, NULL_PTR);
2798 #endif
2799                           /* Remove slash from pl->prefix.  */
2800                           if (strlen (pl->prefix) >= bufsize)
2801                             bufsize = strlen (pl->prefix) * 2 + 1;
2802                           buffer = (char *) xrealloc (buffer, bufsize);
2803                           strcpy (buffer, pl->prefix);
2804                           idx = strlen (buffer);
2805                           if (buffer[idx - 1] == '/')
2806                             buffer[idx - 1] = 0;
2807                           do_spec_1 (buffer, 1, NULL_PTR);
2808                           /* Make this a separate argument.  */
2809                           do_spec_1 (" ", 0, NULL_PTR);
2810                         }
2811                     }
2812                 }
2813               free (buffer);
2814             }
2815             break;
2816
2817           case 'e':
2818             /* {...:%efoo} means report an error with `foo' as error message
2819                and don't execute any more commands for this file.  */
2820             {
2821               char *q = p;
2822               char *buf;
2823               while (*p != 0 && *p != '\n') p++;
2824               buf = (char *) alloca (p - q + 1);
2825               strncpy (buf, q, p - q);
2826               buf[p - q] = 0;
2827               error ("%s", buf);
2828               return -1;
2829             }
2830             break;
2831
2832           case 'g':
2833           case 'u':
2834           case 'U':
2835             if (save_temps_flag)
2836               obstack_grow (&obstack, input_basename, basename_length);
2837             else
2838               {
2839 #ifdef MKTEMP_EACH_FILE
2840                 /* ??? This has a problem: the total number of
2841                    values mktemp can return is limited.
2842                    That matters for the names of object files.
2843                    In 2.4, do something about that.  */
2844                 struct temp_name *t;
2845                 char *suffix = p;
2846                 while (*p == '.' || isalpha (*p))
2847                   p++;
2848
2849                 /* See if we already have an association of %g/%u/%U and
2850                    suffix.  */
2851                 for (t = temp_names; t; t = t->next)
2852                   if (t->length == p - suffix
2853                       && strncmp (t->suffix, suffix, p - suffix) == 0
2854                       && t->unique == (c != 'g'))
2855                     break;
2856
2857                 /* Make a new association if needed.  %u requires one.  */
2858                 if (t == 0 || c == 'u')
2859                   {
2860                     if (t == 0)
2861                       {
2862                         t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
2863                         t->next = temp_names;
2864                         temp_names = t;
2865                       }
2866                     t->length = p - suffix;
2867                     t->suffix = save_string (suffix, p - suffix);
2868                     t->unique = (c != 'g');
2869                     choose_temp_base ();
2870                     t->filename = temp_filename;
2871                     t->filename_length = temp_filename_length;
2872                   }
2873
2874                 obstack_grow (&obstack, t->filename, t->filename_length);
2875                 delete_this_arg = 1;
2876 #else
2877                 obstack_grow (&obstack, temp_filename, temp_filename_length);
2878                 if (c == 'u' || c == 'U')
2879                   {
2880                     static int unique;
2881                     char buff[9];
2882                     if (c == 'u')
2883                       unique++;
2884                     sprintf (buff, "%d", unique);
2885                     obstack_grow (&obstack, buff, strlen (buff));
2886                   }
2887 #endif
2888                 delete_this_arg = 1;
2889               }
2890             arg_going = 1;
2891             break;
2892
2893           case 'i':
2894             obstack_grow (&obstack, input_filename, input_filename_length);
2895             arg_going = 1;
2896             break;
2897
2898           case 'I':
2899             if (gcc_exec_prefix)
2900               {
2901                 do_spec_1 ("-iprefix", 1, NULL_PTR);
2902                 /* Make this a separate argument.  */
2903                 do_spec_1 (" ", 0, NULL_PTR);
2904                 do_spec_1 (gcc_exec_prefix, 1, NULL_PTR);
2905                 do_spec_1 (" ", 0, NULL_PTR);
2906               }
2907             break;
2908
2909           case 'o':
2910             {
2911               register int f;
2912               for (f = 0; f < n_infiles; f++)
2913                 store_arg (outfiles[f], 0, 0);
2914             }
2915             break;
2916
2917           case 's':
2918             this_is_library_file = 1;
2919             break;
2920
2921           case 'w':
2922             this_is_output_file = 1;
2923             break;
2924
2925           case 'W':
2926             {
2927               int index = argbuf_index;
2928               /* Handle the {...} following the %W.  */
2929               if (*p != '{')
2930                 abort ();
2931               p = handle_braces (p + 1);
2932               if (p == 0)
2933                 return -1;
2934               /* If any args were output, mark the last one for deletion
2935                  on failure.  */
2936               if (argbuf_index != index)
2937                 record_temp_file (argbuf[argbuf_index - 1], 0, 1);
2938               break;
2939             }
2940
2941           /* %x{OPTION} records OPTION for %X to output.  */
2942           case 'x':
2943             {
2944               char *p1 = p;
2945               char *string;
2946
2947               /* Skip past the option value and make a copy.  */
2948               if (*p != '{')
2949                 abort ();
2950               while (*p++ != '}')
2951                 ;
2952               string = save_string (p1 + 1, p - p1 - 2);
2953
2954               /* See if we already recorded this option.  */
2955               for (i = 0; i < n_linker_options; i++)
2956                 if (! strcmp (string, linker_options[i]))
2957                   {
2958                     free (string);
2959                     return 0;
2960                   }
2961
2962               /* This option is new; add it.  */
2963               n_linker_options++;
2964               if (!linker_options)
2965                 linker_options
2966                   = (char **) xmalloc (n_linker_options * sizeof (char **));
2967               else
2968                 linker_options
2969                   = (char **) xrealloc (linker_options,
2970                                         n_linker_options * sizeof (char **));
2971
2972               linker_options[n_linker_options - 1] = string;
2973             }
2974             break;
2975
2976           /* Dump out the options accumulated previously using %x,
2977              -Xlinker and -Wl,.  */
2978           case 'X':
2979             for (i = 0; i < n_linker_options; i++)
2980               {
2981                 do_spec_1 (linker_options[i], 1, NULL_PTR);
2982                 /* Make each accumulated option a separate argument.  */
2983                 do_spec_1 (" ", 0, NULL_PTR);
2984               }
2985             break;
2986
2987           /* Dump out the options accumulated previously using -Wa,.  */
2988           case 'Y':
2989             for (i = 0; i < n_assembler_options; i++)
2990               {
2991                 do_spec_1 (assembler_options[i], 1, NULL_PTR);
2992                 /* Make each accumulated option a separate argument.  */
2993                 do_spec_1 (" ", 0, NULL_PTR);
2994               }
2995             break;
2996
2997             /* Here are digits and numbers that just process
2998                a certain constant string as a spec.  */
2999
3000           case '1':
3001             value = do_spec_1 (cc1_spec, 0, NULL_PTR);
3002             if (value != 0)
3003               return value;
3004             break;
3005
3006           case '2':
3007             value = do_spec_1 (cc1plus_spec, 0, NULL_PTR);
3008             if (value != 0)
3009               return value;
3010             break;
3011
3012           case 'a':
3013             value = do_spec_1 (asm_spec, 0, NULL_PTR);
3014             if (value != 0)
3015               return value;
3016             break;
3017
3018           case 'A':
3019             value = do_spec_1 (asm_final_spec, 0, NULL_PTR);
3020             if (value != 0)
3021               return value;
3022             break;
3023
3024           case 'c':
3025             value = do_spec_1 (signed_char_spec, 0, NULL_PTR);
3026             if (value != 0)
3027               return value;
3028             break;
3029
3030           case 'C':
3031             value = do_spec_1 (cpp_spec, 0, NULL_PTR);
3032             if (value != 0)
3033               return value;
3034             break;
3035
3036           case 'E':
3037             value = do_spec_1 (endfile_spec, 0, NULL_PTR);
3038             if (value != 0)
3039               return value;
3040             break;
3041
3042           case 'l':
3043             value = do_spec_1 (link_spec, 0, NULL_PTR);
3044             if (value != 0)
3045               return value;
3046             break;
3047
3048           case 'L':
3049             value = do_spec_1 (lib_spec, 0, NULL_PTR);
3050             if (value != 0)
3051               return value;
3052             break;
3053
3054           case 'p':
3055             {
3056               char *x = (char *) alloca (strlen (cpp_predefines) + 1);
3057               char *buf = x;
3058               char *y;
3059
3060               /* Copy all of the -D options in CPP_PREDEFINES into BUF.  */
3061               y = cpp_predefines;
3062               while (*y != 0)
3063                 {
3064                   if (! strncmp (y, "-D", 2))
3065                     /* Copy the whole option.  */
3066                     while (*y && *y != ' ' && *y != '\t')
3067                       *x++ = *y++;
3068                   else if (*y == ' ' || *y == '\t')
3069                     /* Copy whitespace to the result.  */
3070                     *x++ = *y++;
3071                   /* Don't copy other options.  */
3072                   else
3073                     y++;
3074                 }
3075
3076               *x = 0;
3077
3078               value = do_spec_1 (buf, 0, NULL_PTR);
3079               if (value != 0)
3080                 return value;
3081             }
3082             break;
3083
3084           case 'P':
3085             {
3086               char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
3087               char *buf = x;
3088               char *y;
3089
3090               /* Copy all of CPP_PREDEFINES into BUF,
3091                  but put __ after every -D and at the end of each arg.  */
3092               y = cpp_predefines;
3093               while (*y != 0)
3094                 {
3095                   if (! strncmp (y, "-D", 2))
3096                     {
3097                       int flag = 0;
3098
3099                       *x++ = *y++;
3100                       *x++ = *y++;
3101
3102                       if (strncmp (y, "__", 2))
3103                         {
3104                           /* Stick __ at front of macro name.  */
3105                           *x++ = '_';
3106                           *x++ = '_';
3107                           /* Arrange to stick __ at the end as well.  */
3108                           flag = 1;
3109                         }
3110
3111                       /* Copy the macro name.  */
3112                       while (*y && *y != '=' && *y != ' ' && *y != '\t')
3113                         *x++ = *y++;
3114
3115                       if (flag)
3116                         {
3117                           *x++ = '_';
3118                           *x++ = '_';
3119                         }
3120
3121                       /* Copy the value given, if any.  */
3122                       while (*y && *y != ' ' && *y != '\t')
3123                         *x++ = *y++;
3124                     }
3125                   else if (*y == ' ' || *y == '\t')
3126                     /* Copy whitespace to the result.  */
3127                     *x++ = *y++;
3128                   /* Don't copy -A options  */
3129                   else
3130                     y++;
3131                 }
3132               *x++ = ' ';
3133
3134               /* Copy all of CPP_PREDEFINES into BUF,
3135                  but put __ after every -D.  */
3136               y = cpp_predefines;
3137               while (*y != 0)
3138                 {
3139                   if (! strncmp (y, "-D", 2))
3140                     {
3141                       *x++ = *y++;
3142                       *x++ = *y++;
3143
3144                       if (strncmp (y, "__", 2))
3145                         {
3146                           /* Stick __ at front of macro name.  */
3147                           *x++ = '_';
3148                           *x++ = '_';
3149                         }
3150
3151                       /* Copy the macro name.  */
3152                       while (*y && *y != '=' && *y != ' ' && *y != '\t')
3153                         *x++ = *y++;
3154
3155                       /* Copy the value given, if any.  */
3156                       while (*y && *y != ' ' && *y != '\t')
3157                         *x++ = *y++;
3158                     }
3159                   else if (*y == ' ' || *y == '\t')
3160                     /* Copy whitespace to the result.  */
3161                     *x++ = *y++;
3162                   /* Don't copy -A options  */
3163                   else
3164                     y++;
3165                 }
3166               *x++ = ' ';
3167
3168               /* Copy all of the -A options in CPP_PREDEFINES into BUF.  */
3169               y = cpp_predefines;
3170               while (*y != 0)
3171                 {
3172                   if (! strncmp (y, "-A", 2))
3173                     /* Copy the whole option.  */
3174                     while (*y && *y != ' ' && *y != '\t')
3175                       *x++ = *y++;
3176                   else if (*y == ' ' || *y == '\t')
3177                     /* Copy whitespace to the result.  */
3178                     *x++ = *y++;
3179                   /* Don't copy other options.  */
3180                   else
3181                     y++;
3182                 }
3183
3184               *x = 0;
3185
3186               value = do_spec_1 (buf, 0, NULL_PTR);
3187               if (value != 0)
3188                 return value;
3189             }
3190             break;
3191
3192           case 'S':
3193             value = do_spec_1 (startfile_spec, 0, NULL_PTR);
3194             if (value != 0)
3195               return value;
3196             break;
3197
3198             /* Here we define characters other than letters and digits.  */
3199
3200           case '{':
3201             p = handle_braces (p);
3202             if (p == 0)
3203               return -1;
3204             break;
3205
3206           case '%':
3207             obstack_1grow (&obstack, '%');
3208             break;
3209
3210           case '*':
3211             do_spec_1 (soft_matched_part, 1, NULL_PTR);
3212             do_spec_1 (" ", 0, NULL_PTR);
3213             break;
3214
3215             /* Process a string found as the value of a spec given by name.
3216                This feature allows individual machine descriptions
3217                to add and use their own specs.
3218                %[...] modifies -D options the way %P does;
3219                %(...) uses the spec unmodified.  */
3220           case '(':
3221           case '[':
3222             {
3223               char *name = p;
3224               struct spec_list *sl;
3225               int len;
3226
3227               /* The string after the S/P is the name of a spec that is to be
3228                  processed. */
3229               while (*p && *p != ')' && *p != ']')
3230                 p++;
3231
3232               /* See if it's in the list */
3233               for (len = p - name, sl = specs; sl; sl = sl->next)
3234                 if (strncmp (sl->name, name, len) == 0 && !sl->name[len])
3235                   {
3236                     name = sl->spec;
3237                     break;
3238                   }
3239
3240               if (sl)
3241                 {
3242                   if (c == '(')
3243                     {
3244                       value = do_spec_1 (name, 0, NULL_PTR);
3245                       if (value != 0)
3246                         return value;
3247                     }
3248                   else
3249                     {
3250                       char *x = (char *) alloca (strlen (name) * 2 + 1);
3251                       char *buf = x;
3252                       char *y = name;
3253
3254                       /* Copy all of NAME into BUF, but put __ after
3255                          every -D and at the end of each arg,  */
3256                       while (1)
3257                         {
3258                           if (! strncmp (y, "-D", 2))
3259                             {
3260                               *x++ = '-';
3261                               *x++ = 'D';
3262                               *x++ = '_';
3263                               *x++ = '_';
3264                               y += 2;
3265                             }
3266                           else if (*y == ' ' || *y == 0)
3267                             {
3268                               *x++ = '_';
3269                               *x++ = '_';
3270                               if (*y == 0)
3271                                 break;
3272                               else
3273                                 *x++ = *y++;
3274                             }
3275                           else
3276                             *x++ = *y++;
3277                         }
3278                       *x = 0;
3279
3280                       value = do_spec_1 (buf, 0, NULL_PTR);
3281                       if (value != 0)
3282                         return value;
3283                     }
3284                 }
3285
3286               /* Discard the closing paren or bracket.  */
3287               if (*p)
3288                 p++;
3289             }
3290             break;
3291
3292           case '|':
3293             if (input_from_pipe)
3294               do_spec_1 ("-", 0, NULL_PTR);
3295             break;
3296
3297           default:
3298             abort ();
3299           }
3300         break;
3301
3302       case '\\':
3303         /* Backslash: treat next character as ordinary.  */
3304         c = *p++;
3305
3306         /* fall through */
3307       default:
3308         /* Ordinary character: put it into the current argument.  */
3309         obstack_1grow (&obstack, c);
3310         arg_going = 1;
3311       }
3312
3313   return 0;             /* End of string */
3314 }
3315
3316 /* Return 0 if we call do_spec_1 and that returns -1.  */
3317
3318 static char *
3319 handle_braces (p)
3320      register char *p;
3321 {
3322   register char *q;
3323   char *filter;
3324   int pipe = 0;
3325   int negate = 0;
3326   int suffix = 0;
3327
3328   if (*p == '|')
3329     /* A `|' after the open-brace means,
3330        if the test fails, output a single minus sign rather than nothing.
3331        This is used in %{|!pipe:...}.  */
3332     pipe = 1, ++p;
3333
3334   if (*p == '!')
3335     /* A `!' after the open-brace negates the condition:
3336        succeed if the specified switch is not present.  */
3337     negate = 1, ++p;
3338
3339   if (*p == '.')
3340     /* A `.' after the open-brace means test against the current suffix.  */
3341     {
3342       if (pipe)
3343         abort ();
3344
3345       suffix = 1;
3346       ++p;
3347     }
3348
3349   filter = p;
3350   while (*p != ':' && *p != '}') p++;
3351   if (*p != '}')
3352     {
3353       register int count = 1;
3354       q = p + 1;
3355       while (count > 0)
3356         {
3357           if (*q == '{')
3358             count++;
3359           else if (*q == '}')
3360             count--;
3361           else if (*q == 0)
3362             abort ();
3363           q++;
3364         }
3365     }
3366   else
3367     q = p + 1;
3368
3369   if (suffix)
3370     {
3371       int found = (input_suffix != 0
3372                    && strlen (input_suffix) == p - filter
3373                    && strncmp (input_suffix, filter, p - filter) == 0);
3374
3375       if (p[0] == '}')
3376         abort ();
3377
3378       if (negate != found
3379           && do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0)
3380         return 0;
3381
3382       return q;
3383     }
3384   else if (p[-1] == '*' && p[0] == '}')
3385     {
3386       /* Substitute all matching switches as separate args.  */
3387       register int i;
3388       --p;
3389       for (i = 0; i < n_switches; i++)
3390         if (!strncmp (switches[i].part1, filter, p - filter))
3391           give_switch (i, 0);
3392     }
3393   else
3394     {
3395       /* Test for presence of the specified switch.  */
3396       register int i;
3397       int present = 0;
3398
3399       /* If name specified ends in *, as in {x*:...},
3400          check for %* and handle that case.  */
3401       if (p[-1] == '*' && !negate)
3402         {
3403           int substitution;
3404           char *r = p;
3405
3406           /* First see whether we have %*.  */
3407           substitution = 0;
3408           while (r < q)
3409             {
3410               if (*r == '%' && r[1] == '*')
3411                 substitution = 1;
3412               r++;
3413             }
3414           /* If we do, handle that case.  */
3415           if (substitution)
3416             {
3417               /* Substitute all matching switches as separate args.
3418                  But do this by substituting for %*
3419                  in the text that follows the colon.  */
3420
3421               unsigned hard_match_len = p - filter - 1;
3422               char *string = save_string (p + 1, q - p - 2);
3423
3424               for (i = 0; i < n_switches; i++)
3425                 if (!strncmp (switches[i].part1, filter, hard_match_len))
3426                   {
3427                     do_spec_1 (string, 0, &switches[i].part1[hard_match_len]);
3428                     /* Pass any arguments this switch has.  */
3429                     give_switch (i, 1);
3430                   }
3431
3432               return q;
3433             }
3434         }
3435
3436       /* If name specified ends in *, as in {x*:...},
3437          check for presence of any switch name starting with x.  */
3438       if (p[-1] == '*')
3439         {
3440           for (i = 0; i < n_switches; i++)
3441             {
3442               unsigned hard_match_len = p - filter - 1;
3443
3444               if (!strncmp (switches[i].part1, filter, hard_match_len))
3445                 {
3446                   switches[i].valid = 1;
3447                   present = 1;
3448                 }
3449             }
3450         }
3451       /* Otherwise, check for presence of exact name specified.  */
3452       else
3453         {
3454           for (i = 0; i < n_switches; i++)
3455             {
3456               if (!strncmp (switches[i].part1, filter, p - filter)
3457                   && switches[i].part1[p - filter] == 0)
3458                 {
3459                   switches[i].valid = 1;
3460                   present = 1;
3461                   break;
3462                 }
3463             }
3464         }
3465
3466       /* If it is as desired (present for %{s...}, absent for %{-s...})
3467          then substitute either the switch or the specified
3468          conditional text.  */
3469       if (present != negate)
3470         {
3471           if (*p == '}')
3472             {
3473               give_switch (i, 0);
3474             }
3475           else
3476             {
3477               if (do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0)
3478                 return 0;
3479             }
3480         }
3481       else if (pipe)
3482         {
3483           /* Here if a %{|...} conditional fails: output a minus sign,
3484              which means "standard output" or "standard input".  */
3485           do_spec_1 ("-", 0, NULL_PTR);
3486         }
3487     }
3488
3489   return q;
3490 }
3491
3492 /* Pass a switch to the current accumulating command
3493    in the same form that we received it.
3494    SWITCHNUM identifies the switch; it is an index into
3495    the vector of switches gcc received, which is `switches'.
3496    This cannot fail since it never finishes a command line.
3497
3498    If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
3499
3500 static void
3501 give_switch (switchnum, omit_first_word)
3502      int switchnum;
3503      int omit_first_word;
3504 {
3505   if (!omit_first_word)
3506     {
3507       do_spec_1 ("-", 0, NULL_PTR);
3508       do_spec_1 (switches[switchnum].part1, 1, NULL_PTR);
3509     }
3510   do_spec_1 (" ", 0, NULL_PTR);
3511   if (switches[switchnum].args != 0)
3512     {
3513       char **p;
3514       for (p = switches[switchnum].args; *p; p++)
3515         {
3516           do_spec_1 (*p, 1, NULL_PTR);
3517           do_spec_1 (" ", 0, NULL_PTR);
3518         }
3519     }
3520   switches[switchnum].valid = 1;
3521 }
3522 \f
3523 /* Search for a file named NAME trying various prefixes including the
3524    user's -B prefix and some standard ones.
3525    Return the absolute file name found.  If nothing is found, return NAME.  */
3526
3527 static char *
3528 find_file (name)
3529      char *name;
3530 {
3531   char *newname;
3532
3533   newname = find_a_file (&startfile_prefix, name, R_OK);
3534   return newname ? newname : name;
3535 }
3536
3537 /* Determine whether a directory exists.  If LINKER, return 0 for
3538    certain fixed names not needed by the linker.  If not LINKER, it is
3539    only important to return 0 if the host machine has a small ARG_MAX
3540    limit.  */
3541
3542 static int
3543 is_directory (path1, path2, linker)
3544      char *path1;
3545      char *path2;
3546      int linker;
3547 {
3548   int len1 = strlen (path1);
3549   int len2 = strlen (path2);
3550   char *path = (char *) alloca (3 + len1 + len2);
3551   char *cp;
3552   struct stat st;
3553
3554 #ifndef SMALL_ARG_MAX
3555   if (! linker)
3556     return 1;
3557 #endif
3558
3559   /* Construct the path from the two parts.  Ensure the string ends with "/.".
3560      The resulting path will be a directory even if the given path is a
3561      symbolic link.  */
3562   bcopy (path1, path, len1);
3563   bcopy (path2, path + len1, len2);
3564   cp = path + len1 + len2;
3565   if (cp[-1] != '/')
3566     *cp++ = '/';
3567   *cp++ = '.';
3568   *cp = '\0';
3569
3570   /* Exclude directories that the linker is known to search.  */
3571   if (linker
3572       && ((cp - path == 6 && strcmp (path, "/lib/.") == 0)
3573           || (cp - path == 10 && strcmp (path, "/usr/lib/.") == 0)))
3574     return 0;
3575
3576   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
3577 }
3578 \f
3579 /* On fatal signals, delete all the temporary files.  */
3580
3581 static void
3582 fatal_error (signum)
3583      int signum;
3584 {
3585   signal (signum, SIG_DFL);
3586   delete_failure_queue ();
3587   delete_temp_files ();
3588   /* Get the same signal again, this time not handled,
3589      so its normal effect occurs.  */
3590   kill (getpid (), signum);
3591 }
3592
3593 int
3594 main (argc, argv)
3595      int argc;
3596      char **argv;
3597 {
3598   register int i;
3599   int j;
3600   int value;
3601   int linker_was_run = 0;
3602   char *explicit_link_files;
3603   char *specs_file;
3604   char *p;
3605
3606   p = argv[0] + strlen (argv[0]);
3607   while (p != argv[0] && p[-1] != '/') --p;
3608   programname = p;
3609
3610   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
3611     signal (SIGINT, fatal_error);
3612 #ifdef SIGHUP
3613   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
3614     signal (SIGHUP, fatal_error);
3615 #endif
3616   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
3617     signal (SIGTERM, fatal_error);
3618 #ifdef SIGPIPE
3619   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
3620     signal (SIGPIPE, fatal_error);
3621 #endif
3622
3623   argbuf_length = 10;
3624   argbuf = (char **) xmalloc (argbuf_length * sizeof (char *));
3625
3626   obstack_init (&obstack);
3627
3628   /* Set up to remember the pathname of gcc and any options
3629      needed for collect.  We use argv[0] instead of programname because
3630      we need the complete pathname.  */
3631   obstack_init (&collect_obstack);
3632   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=")-1);
3633   obstack_grow (&collect_obstack, argv[0], strlen (argv[0])+1);
3634   putenv (obstack_finish (&collect_obstack));
3635
3636   /* Choose directory for temp files.  */
3637
3638   choose_temp_base ();
3639
3640   /* Make a table of what switches there are (switches, n_switches).
3641      Make a table of specified input files (infiles, n_infiles).
3642      Decode switches that are handled locally.  */
3643
3644   process_command (argc, argv);
3645
3646   /* Initialize the vector of specs to just the default.
3647      This means one element containing 0s, as a terminator.  */
3648
3649   compilers = (struct compiler *) xmalloc (sizeof default_compilers);
3650   bcopy (default_compilers, compilers, sizeof default_compilers);
3651   n_compilers = n_default_compilers;
3652
3653   /* Read specs from a file if there is one.  */
3654
3655   machine_suffix = concat (spec_machine, "/", concat (spec_version, "/", ""));
3656   just_machine_suffix = concat (spec_machine, "/", "");
3657
3658   specs_file = find_a_file (&startfile_prefix, "specs", R_OK);
3659   /* Read the specs file unless it is a default one.  */
3660   if (specs_file != 0 && strcmp (specs_file, "specs"))
3661     read_specs (specs_file);
3662
3663   /* If not cross-compiling, look for startfiles in the standard places.  */
3664   /* The fact that these are done here, after reading the specs file,
3665      means that it cannot be found in these directories.
3666      But that's okay.  It should never be there anyway.  */
3667   if (!cross_compile)
3668     {
3669 #ifdef MD_EXEC_PREFIX
3670       add_prefix (&exec_prefix, md_exec_prefix, 0, 0, NULL_PTR);
3671       add_prefix (&startfile_prefix, md_exec_prefix, 0, 0, NULL_PTR);
3672 #endif
3673
3674 #ifdef MD_STARTFILE_PREFIX
3675       add_prefix (&startfile_prefix, md_startfile_prefix, 0, 0, NULL_PTR);
3676 #endif
3677
3678 #ifdef MD_STARTFILE_PREFIX_1
3679       add_prefix (&startfile_prefix, md_startfile_prefix_1, 0, 0, NULL_PTR);
3680 #endif
3681
3682       add_prefix (&startfile_prefix, standard_startfile_prefix, 0, 0,
3683                   NULL_PTR);
3684       add_prefix (&startfile_prefix, standard_startfile_prefix_1, 0, 0,
3685                   NULL_PTR);
3686       add_prefix (&startfile_prefix, standard_startfile_prefix_2, 0, 0,
3687                   NULL_PTR);
3688 #if 0 /* Can cause surprises, and one can use -B./ instead.  */
3689       add_prefix (&startfile_prefix, "./", 0, 1, NULL_PTR);
3690 #endif
3691     }
3692
3693   /* Now we have the specs.
3694      Set the `valid' bits for switches that match anything in any spec.  */
3695
3696   validate_all_switches ();
3697
3698   /* Warn about any switches that no pass was interested in.  */
3699
3700   for (i = 0; i < n_switches; i++)
3701     if (! switches[i].valid)
3702       error ("unrecognized option `-%s'", switches[i].part1);
3703
3704   if (print_libgcc_file_name)
3705     {
3706       printf ("%s\n", find_file ("libgcc.a"));
3707       exit (0);
3708     }
3709
3710   /* Obey some of the options.  */
3711
3712   if (verbose_flag)
3713     {
3714       fprintf (stderr, "gcc version %s\n", version_string);
3715       if (n_infiles == 0)
3716         exit (0);
3717     }
3718
3719   if (n_infiles == 0)
3720     fatal ("No input files specified.");
3721
3722   /* Make a place to record the compiler output file names
3723      that correspond to the input files.  */
3724
3725   outfiles = (char **) xmalloc (n_infiles * sizeof (char *));
3726   bzero (outfiles, n_infiles * sizeof (char *));
3727
3728   /* Record which files were specified explicitly as link input.  */
3729
3730   explicit_link_files = xmalloc (n_infiles);
3731   bzero (explicit_link_files, n_infiles);
3732
3733   for (i = 0; i < n_infiles; i++)
3734     {
3735       register struct compiler *cp = 0;
3736       int this_file_error = 0;
3737
3738       /* Tell do_spec what to substitute for %i.  */
3739
3740       input_filename = infiles[i].name;
3741       input_filename_length = strlen (input_filename);
3742       input_file_number = i;
3743
3744       /* Use the same thing in %o, unless cp->spec says otherwise.  */
3745
3746       outfiles[i] = input_filename;
3747
3748       /* Figure out which compiler from the file's suffix.  */
3749
3750       cp = lookup_compiler (infiles[i].name, input_filename_length,
3751                             infiles[i].language);
3752
3753       if (cp)
3754         {
3755           /* Ok, we found an applicable compiler.  Run its spec.  */
3756           /* First say how much of input_filename to substitute for %b  */
3757           register char *p;
3758           int len;
3759
3760           input_basename = input_filename;
3761           for (p = input_filename; *p; p++)
3762             if (*p == '/')
3763               input_basename = p + 1;
3764
3765           /* Find a suffix starting with the last period,
3766              and set basename_length to exclude that suffix.  */
3767           basename_length = strlen (input_basename);
3768           p = input_basename + basename_length;
3769           while (p != input_basename && *p != '.') --p;
3770           if (*p == '.' && p != input_basename)
3771             {
3772               basename_length = p - input_basename;
3773               input_suffix = p + 1;
3774             }
3775           else
3776             input_suffix = "";
3777
3778           len = 0;
3779           for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
3780             if (cp->spec[j])
3781               len += strlen (cp->spec[j]);
3782
3783           p = (char *) xmalloc (len + 1);
3784
3785           len = 0;
3786           for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
3787             if (cp->spec[j])
3788               {
3789                 strcpy (p + len, cp->spec[j]);
3790                 len += strlen (cp->spec[j]);
3791               }
3792
3793           value = do_spec (p);
3794           free (p);
3795           if (value < 0)
3796             this_file_error = 1;
3797         }
3798
3799       /* If this file's name does not contain a recognized suffix,
3800          record it as explicit linker input.  */
3801
3802       else
3803         explicit_link_files[i] = 1;
3804
3805       /* Clear the delete-on-failure queue, deleting the files in it
3806          if this compilation failed.  */
3807
3808       if (this_file_error)
3809         {
3810           delete_failure_queue ();
3811           error_count++;
3812         }
3813       /* If this compilation succeeded, don't delete those files later.  */
3814       clear_failure_queue ();
3815     }
3816
3817   /* Run ld to link all the compiler output files.  */
3818
3819   if (error_count == 0)
3820     {
3821       int tmp = execution_count;
3822       int i;
3823       int first_time;
3824
3825       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
3826          for collect.  */
3827       putenv_from_prefixes (&exec_prefix, "COMPILER_PATH=");
3828       putenv_from_prefixes (&startfile_prefix, "LIBRARY_PATH=");
3829
3830       /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
3831          the compiler.  */
3832       obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
3833                     sizeof ("COLLECT_GCC_OPTIONS=")-1);
3834
3835       first_time = TRUE;
3836       for (i = 0; i < n_switches; i++)
3837         {
3838           char **args;
3839           if (!first_time)
3840             obstack_grow (&collect_obstack, " ", 1);
3841
3842           first_time = FALSE;
3843           obstack_grow (&collect_obstack, "-", 1);
3844           obstack_grow (&collect_obstack, switches[i].part1,
3845                         strlen (switches[i].part1));
3846
3847           for (args = switches[i].args; args && *args; args++)
3848             {
3849               obstack_grow (&collect_obstack, " ", 1);
3850               obstack_grow (&collect_obstack, *args, strlen (*args));
3851             }
3852         }
3853       obstack_grow (&collect_obstack, "\0", 1);
3854       putenv (obstack_finish (&collect_obstack));
3855
3856       value = do_spec (link_command_spec);
3857       if (value < 0)
3858         error_count = 1;
3859       linker_was_run = (tmp != execution_count);
3860     }
3861
3862   /* Warn if a -B option was specified but the prefix was never used.  */
3863   unused_prefix_warnings (&exec_prefix);
3864   unused_prefix_warnings (&startfile_prefix);
3865
3866   /* If options said don't run linker,
3867      complain about input files to be given to the linker.  */
3868
3869   if (! linker_was_run && error_count == 0)
3870     for (i = 0; i < n_infiles; i++)
3871       if (explicit_link_files[i])
3872         error ("%s: linker input file unused since linking not done",
3873                outfiles[i]);
3874
3875   /* Delete some or all of the temporary files we made.  */
3876
3877   if (error_count)
3878     delete_failure_queue ();
3879   delete_temp_files ();
3880
3881   exit (error_count > 0 ? (signal_count ? 2 : 1) : 0);
3882   /* NOTREACHED */
3883   return 0;
3884 }
3885
3886 /* Find the proper compilation spec for the file name NAME,
3887    whose length is LENGTH.  LANGUAGE is the specified language,
3888    or 0 if none specified.  */
3889
3890 static struct compiler *
3891 lookup_compiler (name, length, language)
3892      char *name;
3893      int length;
3894      char *language;
3895 {
3896   struct compiler *cp;
3897
3898   /* Look for the language, if one is spec'd.  */
3899   if (language != 0)
3900     {
3901       for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
3902         {
3903           if (language != 0)
3904             {
3905               if (cp->suffix[0] == '@'
3906                   && !strcmp (cp->suffix + 1, language))
3907                 return cp;
3908             }
3909         }
3910       error ("language %s not recognized", language);
3911     }
3912
3913   /* Look for a suffix.  */
3914   for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
3915     {
3916       if (/* The suffix `-' matches only the file name `-'.  */
3917           (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
3918           ||
3919           (strlen (cp->suffix) < length
3920            /* See if the suffix matches the end of NAME.  */
3921            && !strcmp (cp->suffix,
3922                        name + length - strlen (cp->suffix))))
3923         {
3924           if (cp->spec[0][0] == '@')
3925             {
3926               struct compiler *new;
3927               /* An alias entry maps a suffix to a language.
3928                  Search for the language; pass 0 for NAME and LENGTH
3929                  to avoid infinite recursion if language not found.
3930                  Construct the new compiler spec.  */
3931               language = cp->spec[0] + 1;
3932               new = (struct compiler *) xmalloc (sizeof (struct compiler));
3933               new->suffix = cp->suffix;
3934               bcopy (lookup_compiler (NULL_PTR, 0, language)->spec,
3935                      new->spec, sizeof new->spec);
3936               return new;
3937             }
3938           /* A non-alias entry: return it.  */
3939           return cp;
3940         }
3941     }
3942
3943   return 0;
3944 }
3945 \f
3946 char *
3947 xmalloc (size)
3948      unsigned size;
3949 {
3950   register char *value = (char *) malloc (size);
3951   if (value == 0)
3952     fatal ("virtual memory exhausted");
3953   return value;
3954 }
3955
3956 char *
3957 xrealloc (ptr, size)
3958      char *ptr;
3959      unsigned size;
3960 {
3961   register char *value = (char *) realloc (ptr, size);
3962   if (value == 0)
3963     fatal ("virtual memory exhausted");
3964   return value;
3965 }
3966
3967 /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3.  */
3968
3969 static char *
3970 concat (s1, s2, s3)
3971      char *s1, *s2, *s3;
3972 {
3973   int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
3974   char *result = xmalloc (len1 + len2 + len3 + 1);
3975
3976   strcpy (result, s1);
3977   strcpy (result + len1, s2);
3978   strcpy (result + len1 + len2, s3);
3979   *(result + len1 + len2 + len3) = 0;
3980
3981   return result;
3982 }
3983
3984 static char *
3985 save_string (s, len)
3986      char *s;
3987      int len;
3988 {
3989   register char *result = xmalloc (len + 1);
3990
3991   bcopy (s, result, len);
3992   result[len] = 0;
3993   return result;
3994 }
3995
3996 static void
3997 pfatal_with_name (name)
3998      char *name;
3999 {
4000   char *s;
4001
4002   if (errno < sys_nerr)
4003     s = concat ("%s: ", sys_errlist[errno], "");
4004   else
4005     s = "cannot open %s";
4006   fatal (s, name);
4007 }
4008
4009 static void
4010 perror_with_name (name)
4011      char *name;
4012 {
4013   char *s;
4014
4015   if (errno < sys_nerr)
4016     s = concat ("%s: ", sys_errlist[errno], "");
4017   else
4018     s = "cannot open %s";
4019   error (s, name);
4020 }
4021
4022 static void
4023 perror_exec (name)
4024      char *name;
4025 {
4026   char *s;
4027
4028   if (errno < sys_nerr)
4029     s = concat ("installation problem, cannot exec %s: ",
4030                 sys_errlist[errno], "");
4031   else
4032     s = "installation problem, cannot exec %s";
4033   error (s, name);
4034 }
4035
4036 /* More 'friendly' abort that prints the line and file.
4037    config.h can #define abort fancy_abort if you like that sort of thing.  */
4038
4039 void
4040 fancy_abort ()
4041 {
4042   fatal ("Internal gcc abort.");
4043 }
4044 \f
4045 #ifdef HAVE_VPRINTF
4046
4047 /* Output an error message and exit */
4048
4049 static void
4050 fatal (va_alist)
4051      va_dcl
4052 {
4053   va_list ap;
4054   char *format;
4055
4056   va_start (ap);
4057   format = va_arg (ap, char *);
4058   fprintf (stderr, "%s: ", programname);
4059   vfprintf (stderr, format, ap);
4060   va_end (ap);
4061   fprintf (stderr, "\n");
4062   delete_temp_files ();
4063   exit (1);
4064 }
4065
4066 static void
4067 error (va_alist)
4068      va_dcl
4069 {
4070   va_list ap;
4071   char *format;
4072
4073   va_start (ap);
4074   format = va_arg (ap, char *);
4075   fprintf (stderr, "%s: ", programname);
4076   vfprintf (stderr, format, ap);
4077   va_end (ap);
4078
4079   fprintf (stderr, "\n");
4080 }
4081
4082 #else /* not HAVE_VPRINTF */
4083
4084 static void
4085 fatal (msg, arg1, arg2)
4086      char *msg, *arg1, *arg2;
4087 {
4088   error (msg, arg1, arg2);
4089   delete_temp_files ();
4090   exit (1);
4091 }
4092
4093 static void
4094 error (msg, arg1, arg2)
4095      char *msg, *arg1, *arg2;
4096 {
4097   fprintf (stderr, "%s: ", programname);
4098   fprintf (stderr, msg, arg1, arg2);
4099   fprintf (stderr, "\n");
4100 }
4101
4102 #endif /* not HAVE_VPRINTF */
4103
4104 \f
4105 static void
4106 validate_all_switches ()
4107 {
4108   struct compiler *comp;
4109   register char *p;
4110   register char c;
4111   struct spec_list *spec;
4112
4113   for (comp = compilers; comp->spec[0]; comp++)
4114     {
4115       int i;
4116       for (i = 0; i < sizeof comp->spec / sizeof comp->spec[0] && comp->spec[i]; i++)
4117         {
4118           p = comp->spec[i];
4119           while (c = *p++)
4120             if (c == '%' && *p == '{')
4121               /* We have a switch spec.  */
4122               validate_switches (p + 1);
4123         }
4124     }
4125
4126   /* look through the linked list of extra specs read from the specs file */
4127   for (spec = specs; spec ; spec = spec->next)
4128     {
4129       p = spec->spec;
4130       while (c = *p++)
4131         if (c == '%' && *p == '{')
4132           /* We have a switch spec.  */
4133           validate_switches (p + 1);
4134     }
4135
4136   p = link_command_spec;
4137   while (c = *p++)
4138     if (c == '%' && *p == '{')
4139       /* We have a switch spec.  */
4140       validate_switches (p + 1);
4141
4142   /* Now notice switches mentioned in the machine-specific specs.  */
4143
4144   p = asm_spec;
4145   while (c = *p++)
4146     if (c == '%' && *p == '{')
4147       /* We have a switch spec.  */
4148       validate_switches (p + 1);
4149
4150   p = asm_final_spec;
4151   while (c = *p++)
4152     if (c == '%' && *p == '{')
4153       /* We have a switch spec.  */
4154       validate_switches (p + 1);
4155
4156   p = cpp_spec;
4157   while (c = *p++)
4158     if (c == '%' && *p == '{')
4159       /* We have a switch spec.  */
4160       validate_switches (p + 1);
4161
4162   p = signed_char_spec;
4163   while (c = *p++)
4164     if (c == '%' && *p == '{')
4165       /* We have a switch spec.  */
4166       validate_switches (p + 1);
4167
4168   p = cc1_spec;
4169   while (c = *p++)
4170     if (c == '%' && *p == '{')
4171       /* We have a switch spec.  */
4172       validate_switches (p + 1);
4173
4174   p = cc1plus_spec;
4175   while (c = *p++)
4176     if (c == '%' && *p == '{')
4177       /* We have a switch spec.  */
4178       validate_switches (p + 1);
4179
4180   p = link_spec;
4181   while (c = *p++)
4182     if (c == '%' && *p == '{')
4183       /* We have a switch spec.  */
4184       validate_switches (p + 1);
4185
4186   p = lib_spec;
4187   while (c = *p++)
4188     if (c == '%' && *p == '{')
4189       /* We have a switch spec.  */
4190       validate_switches (p + 1);
4191
4192   p = startfile_spec;
4193   while (c = *p++)
4194     if (c == '%' && *p == '{')
4195       /* We have a switch spec.  */
4196       validate_switches (p + 1);
4197 }
4198
4199 /* Look at the switch-name that comes after START
4200    and mark as valid all supplied switches that match it.  */
4201
4202 static void
4203 validate_switches (start)
4204      char *start;
4205 {
4206   register char *p = start;
4207   char *filter;
4208   register int i;
4209   int suffix = 0;
4210
4211   if (*p == '|')
4212     ++p;
4213
4214   if (*p == '!')
4215     ++p;
4216
4217   if (*p == '.')
4218     suffix = 1, ++p;
4219
4220   filter = p;
4221   while (*p != ':' && *p != '}') p++;
4222
4223   if (suffix)
4224     ;
4225   else if (p[-1] == '*')
4226     {
4227       /* Mark all matching switches as valid.  */
4228       --p;
4229       for (i = 0; i < n_switches; i++)
4230         if (!strncmp (switches[i].part1, filter, p - filter))
4231           switches[i].valid = 1;
4232     }
4233   else
4234     {
4235       /* Mark an exact matching switch as valid.  */
4236       for (i = 0; i < n_switches; i++)
4237         {
4238           if (!strncmp (switches[i].part1, filter, p - filter)
4239               && switches[i].part1[p - filter] == 0)
4240             switches[i].valid = 1;
4241         }
4242     }
4243 }