OSDN Git Service

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