|
|
1.1 root 1: /* Compiler driver program that can handle many languages.
2: Copyright (C) 1987, 1989, 1992, 1993 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:
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: #ifdef NeXT
39: #include <sys/param.h>
40: #include <sys/time.h>
41: #endif
42:
43: #include "config.h"
44: #include "obstack.h"
45: #include "gvarargs.h"
46: #include <stdio.h>
47:
48: #ifndef R_OK
49: #define R_OK 4
50: #define W_OK 2
51: #define X_OK 1
52: #endif
53:
54: /* Define a generic NULL if one hasn't already been defined. */
55:
56: #ifndef NULL
57: #define NULL 0
58: #endif
59:
60: #ifndef GENERIC_PTR
61: #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
62: #define GENERIC_PTR void *
63: #else
64: #define GENERIC_PTR char *
65: #endif
66: #endif
67:
68: #ifndef NULL_PTR
69: #define NULL_PTR ((GENERIC_PTR)0)
70: #endif
71:
72: #ifdef USG
73: #define vfork fork
74: #endif /* USG */
75:
76: /* On MSDOS, write temp files in current dir
77: because there's no place else we can expect to use. */
78: #if __MSDOS__
79: #ifndef P_tmpdir
80: #define P_tmpdir "."
81: #endif
82: #endif
83:
84: /* Test if something is a normal file. */
85: #ifndef S_ISREG
86: #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
87: #endif
88:
89: /* Test if something is a directory. */
90: #ifndef S_ISDIR
91: #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
92: #endif
93:
94: /* By default there is no special suffix for executables. */
95: #ifndef EXECUTABLE_SUFFIX
96: #define EXECUTABLE_SUFFIX ""
97: #endif
98:
99: /* By default, colon separates directories in a path. */
100: #ifndef PATH_SEPARATOR
101: #define PATH_SEPARATOR ':'
102: #endif
103:
104: #define obstack_chunk_alloc xmalloc
105: #define obstack_chunk_free free
106:
107: extern void free ();
108: extern char *getenv ();
109:
110: extern int errno, sys_nerr;
111: #if defined(bsd4_4)
112: extern const char *const sys_errlist[];
113: #else
114: extern char *sys_errlist[];
115: #endif
116:
117: extern int execv (), execvp ();
118:
119: /* If a stage of compilation returns an exit status >= 1,
120: compilation of that file ceases. */
121:
122: #define MIN_FATAL_STATUS 1
123:
124: /* Flag saying to print the full filename of libgcc.a
125: as found through our usual search mechanism. */
126:
127: static int print_libgcc_file_name;
128:
129: /* Flag saying to dump the specs from the specs file
130: as found through our usual search mechanism. */
131:
132: static int dump_specs;
133:
134: /* Flag indicating whether we should print the command and arguments */
135:
136: static int verbose_flag;
137:
138: /* Nonzero means write "temp" files in source directory
139: and use the source file's name in them, and don't delete them. */
140:
141: static int save_temps_flag;
142:
143: /* The compiler version specified with -V */
144:
145: static char *spec_version;
146:
147: /* The target machine specified with -b. */
148:
149: static char *spec_machine = DEFAULT_TARGET_MACHINE;
150:
151: /* Nonzero if cross-compiling.
152: When -b is used, the value comes from the `specs' file. */
153:
154: #ifdef CROSS_COMPILE
155: static int cross_compile = 1;
156: #else
157: static int cross_compile = 0;
158: #endif
159:
160: #ifdef NEXT_FAT_OUTPUT
161: #include <mach-o/arch.h>
162:
163: /* An array of architectures sepcified with -arch. */
164: unsigned int current_arch;
165: unsigned int arch_count = 0;
166: NXArchInfo const **arch_array = NULL;
167: char **arch_family = NULL;
168: unsigned int multi_arch = 0;
169: unsigned int run_siff = 0;
170: #endif /* NEXT_FAT_OUTPUT */
171:
172: #ifdef REPORT_EVENT
173: int re_type, re_line, re_arg1, re_arg2, re_arg3, re_ok;
174: char *re_name, *re_file, *re_msg;
175: #define SAVE_REPORT_EVENT(TYPE, NAME, FILE, LINE, MSG, ARG1, ARG2, ARG3) \
176: re_type = (TYPE), re_name = (NAME), re_file = (FILE), re_line = (LINE), \
177: re_msg = (MSG), re_arg1 = (int)(ARG1), re_arg2 = (int)(ARG2), \
178: re_arg3 = (int)(ARG3), re_ok = 1
179: #define DO_REPORT_EVENT() \
180: do { \
181: if (re_ok) \
182: REPORT_EVENT (re_type, re_name, re_file, re_line, \
183: re_msg, re_arg1, re_arg2, re_arg3); \
184: re_ok = 0; \
185: } while (0)
186: #define DO_REPORT_STAGE(STAGE) \
187: do { \
188: if (multi_arch) \
189: REPORT_EVENT (re_type, re_name, re_file, re_line, \
190: STAGE " for %s", \
191: arch_array[current_arch]->name, re_arg2, re_arg3); \
192: else \
193: REPORT_EVENT (re_type, re_name, re_file, re_line, \
194: STAGE, re_arg1, re_arg2, re_arg3); \
195: } while (0)
196: #endif
197:
198: /* The number of errors that have occurred; the link phase will not be
199: run if this is non-zero. */
200: static int error_count = 0;
201:
202: /* This is the obstack which we use to allocate many strings. */
203:
204: static struct obstack obstack;
205:
206: /* This is the obstack to build an environment variable to pass to
207: collect2 that describes all of the relevant switches of what to
208: pass the compiler in building the list of pointers to constructors
209: and destructors. */
210:
211: static struct obstack collect_obstack;
212:
213: extern char *version_string;
214:
215: static void set_spec ();
216: static struct compiler *lookup_compiler ();
217: static char *find_a_file ();
218: static void add_prefix ();
219: static char *skip_whitespace ();
220: static void record_temp_file ();
221: static char *handle_braces ();
222: static char *save_string ();
223: static char *concat ();
224: static int do_spec ();
225: static int do_spec_1 ();
226: static char *find_file ();
227: static int is_directory ();
228: static void validate_switches ();
229: static void validate_all_switches ();
230: static void give_switch ();
231: static void pfatal_with_name ();
232: static void perror_with_name ();
233: static void perror_exec ();
234: static void fatal ();
235: static void error ();
236: void fancy_abort ();
237: char *xmalloc ();
238: char *xrealloc ();
239:
240: /* Specs are strings containing lines, each of which (if not blank)
241: is made up of a program name, and arguments separated by spaces.
242: The program name must be exact and start from root, since no path
243: is searched and it is unreliable to depend on the current working directory.
244: Redirection of input or output is not supported; the subprograms must
245: accept filenames saying what files to read and write.
246:
247: In addition, the specs can contain %-sequences to substitute variable text
248: or for conditional text. Here is a table of all defined %-sequences.
249: Note that spaces are not generated automatically around the results of
250: expanding these sequences; therefore, you can concatenate them together
251: or with constant text in a single argument.
252:
253: %% substitute one % into the program name or argument.
254: %i substitute the name of the input file being processed.
255: %b substitute the basename of the input file being processed.
256: This is the substring up to (and not including) the last period
257: and not including the directory.
258: %g substitute the temporary-file-name-base. This is a string chosen
259: once per compilation. Different temporary file names are made by
260: concatenation of constant strings on the end, as in `%g.s'.
261: %g also has the same effect of %d.
262: %u like %g, but make the temporary file name unique.
263: %U returns the last file name generated with %u.
264: %d marks the argument containing or following the %d as a
265: temporary file name, so that that file will be deleted if CC exits
266: successfully. Unlike %g, this contributes no text to the argument.
267: %w marks the argument containing or following the %w as the
268: "output file" of this compilation. This puts the argument
269: into the sequence of arguments that %o will substitute later.
270: %W{...}
271: like %{...} but mark last argument supplied within
272: as a file to be deleted on failure.
273: %ifdef NEXT_FAT_OUTPUT
274: %f marks the argument following the %f as the "output file" of this
275: compilation for multi-architecture builds. This puts the argument
276: into the sequence of arguments that %F will substitute later.
277: %F substitutes the names of all the intermediate architecture files,
278: with spaces automatically placed around them. You should write spaces
279: around the %F as well or the results are undefined.
280: %F is for use in the specs for running the architecture merger.
281: %T substitutes the name of the current architecture.
282: %endif
283: %o substitutes the names of all the output files, with spaces
284: automatically placed around them. You should write spaces
285: around the %o as well or the results are undefined.
286: %o is for use in the specs for running the linker.
287: Input files whose names have no recognized suffix are not compiled
288: at all, but they are included among the output files, so they will
289: be linked.
290: %ifdef NeXT
291: %p substitutes the standard macro predefinitions for the current target
292: machine that violate the ANSI C namespace rules (those that do not
293: begin with `__'). Use this when running cpp when -ansi is not
294: specified.
295: %endif
296: %P like %p, but puts `__' before and after the name of each macro.
297: (Except macros that already have __.)
298: This is for ANSI C.
299: %I Substitute a -iprefix option made from GCC_EXEC_PREFIX.
300: %s current argument is the name of a library or startup file of some sort.
301: Search for that file in a standard list of directories
302: and substitute the full name found.
303: %eSTR Print STR as an error message. STR is terminated by a newline.
304: Use this when inconsistent options are detected.
305: %x{OPTION} Accumulate an option for %X.
306: %X Output the accumulated linker options specified by compilations.
307: %Y Output the accumulated assembler options specified by compilations.
308: %v1 Substitute the major version number of GCC.
309: (For version 2.5.n, this is 2.)
310: %v2 Substitute the minor version number of GCC.
311: (For version 2.5.n, this is 5.)
312: %a process ASM_SPEC as a spec.
313: This allows config.h to specify part of the spec for running as.
314: %A process ASM_FINAL_SPEC as a spec. A capital A is actually
315: used here. This can be used to run a post-processor after the
316: assembler has done it's job.
317: %D Dump out a -L option for each directory in startfile_prefix.
318: %ifdef NEXT_FAT_OUTPUT
319: %M substitutes the dependency file name (e.g. foo.d).
320: %endif
321: %l process LINK_SPEC as a spec.
322: %L process LIB_SPEC as a spec.
323: %S process STARTFILE_SPEC as a spec. A capital S is actually used here.
324: %E process ENDFILE_SPEC as a spec. A capital E is actually used here.
325: %c process SIGNED_CHAR_SPEC as a spec.
326: %C process CPP_SPEC as a spec. A capital C is actually used here.
327: %1 process CC1_SPEC as a spec.
328: %2 process CC1PLUS_SPEC as a spec.
329: %| output "-" if the input for the current command is coming from a pipe.
330: %* substitute the variable part of a matched option. (See below.)
331: Note that each comma in the substituted string is replaced by
332: a single space.
333: %{S} substitutes the -S switch, if that switch was given to CC.
334: If that switch was not specified, this substitutes nothing.
335: Here S is a metasyntactic variable.
336: %{S*} substitutes all the switches specified to CC whose names start
337: with -S. This is used for -o, -D, -I, etc; switches that take
338: arguments. CC considers `-o foo' as being one switch whose
339: name starts with `o'. %{o*} would substitute this text,
340: including the space; thus, two arguments would be generated.
341: %{S*:X} substitutes X if one or more switches whose names start with -S are
342: specified to CC. Note that the tail part of the -S option
343: (i.e. the part matched by the `*') will be substituted for each
344: occurrence of %* within X.
345: %{S:X} substitutes X, but only if the -S switch was given to CC.
346: %{!S:X} substitutes X, but only if the -S switch was NOT given to CC.
347: %{|S:X} like %{S:X}, but if no S switch, substitute `-'.
348: %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
349: %{.S:X} substitutes X, but only if processing a file with suffix S.
350: %{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
351: %ifdef NEXT_FAT_OUTPUT
352: %{@:X} substitutes X, but only if processing multiple architectures.
353: %{!@:X} substitutes X, but only if NOT processing multiple architectures.
354: %endif
355: %(Spec) processes a specification defined in a specs file as *Spec:
356: %[Spec] as above, but put __ around -D arguments
357: %{S1|S2|...:X} Tests S1, S2, ... in sequence. If any of the
358: switches S1, S2 ... was given to CC it substitutes X.
359: The tests can include negation !, wildcard *, and suffix .
360: notations above.
361: %{S:X}%:{Y} substitutes Y if condition S fails. Otherwise
362: substitutes X as described by the rules above. The S condition
363: can be any of the constructs listed above, including the
364:
365: The conditional text X in a %{S:X} or %{!S:X} construct may contain
366: other nested % constructs or spaces, or even newlines. They are
367: processed as usual, as described above.
368:
369: The character | is used to indicate that a command should be piped to
370: the following command, but only if -pipe is specified.
371:
372: Note that it is built into CC which switches take arguments and which
373: do not. You might think it would be useful to generalize this to
374: allow each compiler's spec to say which switches take arguments. But
375: this cannot be done in a consistent fashion. CC cannot even decide
376: which input files have been specified without knowing which switches
377: take arguments, and it must know which input files to compile in order
378: to tell which compilers to run.
379:
380: CC also knows implicitly that arguments starting in `-l' are to be
381: treated as compiler output files, and passed to the linker in their
382: proper position among the other output files. */
383:
384: /* Define the macros used for specs %a, %l, %L, %S, %c, %C, %1. */
385:
386: /* config.h can define ASM_SPEC to provide extra args to the assembler
387: or extra switch-translations. */
388: #ifndef ASM_SPEC
389: #define ASM_SPEC ""
390: #endif
391:
392: /* config.h can define ASM_FINAL_SPEC to run a post processor after
393: the assembler has run. */
394: #ifndef ASM_FINAL_SPEC
395: #define ASM_FINAL_SPEC ""
396: #endif
397:
398: /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
399: or extra switch-translations. */
400: #ifndef CPP_SPEC
401: #define CPP_SPEC ""
402: #endif
403:
404: /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
405: or extra switch-translations. */
406: #ifndef CC1_SPEC
407: #define CC1_SPEC ""
408: #endif
409:
410: /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
411: or extra switch-translations. */
412: #ifndef CC1PLUS_SPEC
413: #define CC1PLUS_SPEC ""
414: #endif
415:
416: /* config.h can define LINK_SPEC to provide extra args to the linker
417: or extra switch-translations. */
418: #ifndef LINK_SPEC
419: #define LINK_SPEC ""
420: #endif
421:
422: /* config.h can define LIB_SPEC to override the default libraries. */
423: #ifndef LIB_SPEC
424: #define LIB_SPEC "%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
425: #endif
426:
427: /* config.h can define STARTFILE_SPEC to override the default crt0 files. */
428: #ifndef STARTFILE_SPEC
429: #define STARTFILE_SPEC \
430: "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
431: #endif
432:
433: /* config.h can define SWITCHES_NEED_SPACES to control passing -o and -L.
434: Make the string nonempty to require spaces there. */
435: #ifndef SWITCHES_NEED_SPACES
436: #define SWITCHES_NEED_SPACES ""
437: #endif
438:
439: /* config.h can define ENDFILE_SPEC to override the default crtn files. */
440: #ifndef ENDFILE_SPEC
441: #define ENDFILE_SPEC ""
442: #endif
443:
444: /* This spec is used for telling cpp whether char is signed or not. */
445: #ifndef SIGNED_CHAR_SPEC
446: /* Use #if rather than ?:
447: because MIPS C compiler rejects like ?: in initializers. */
448: #if DEFAULT_SIGNED_CHAR
449: #define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
450: #else
451: #define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}"
452: #endif
453: #endif
454:
455: static char *cpp_spec = CPP_SPEC;
456: static char *cpp_predefines = CPP_PREDEFINES;
457: static char *cc1_spec = CC1_SPEC;
458: static char *cc1plus_spec = CC1PLUS_SPEC;
459: static char *signed_char_spec = SIGNED_CHAR_SPEC;
460: static char *asm_spec = ASM_SPEC;
461: static char *asm_final_spec = ASM_FINAL_SPEC;
462: static char *link_spec = LINK_SPEC;
463: static char *lib_spec = LIB_SPEC;
464: static char *endfile_spec = ENDFILE_SPEC;
465: static char *startfile_spec = STARTFILE_SPEC;
466: static char *switches_need_spaces = SWITCHES_NEED_SPACES;
467:
468: /* This defines which switch letters take arguments. */
469:
470: #ifndef SWITCH_TAKES_ARG
471: #define SWITCH_TAKES_ARG(CHAR) \
472: ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
473: || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
474: || (CHAR) == 'I' || (CHAR) == 'm' \
475: || (CHAR) == 'L' || (CHAR) == 'A')
476: #endif
477:
478: /* This defines which multi-letter switches take arguments. */
479:
480: #define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \
481: (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \
482: || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \
483: || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
484: || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
485: || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore"))
486:
487: #ifndef WORD_SWITCH_TAKES_ARG
488: #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
489: #endif
490:
491: /* Record the mapping from file suffixes for compilation specs. */
492:
493: struct compiler
494: {
495: char *suffix; /* Use this compiler for input files
496: whose names end in this suffix. */
497:
498: char *spec[4]; /* To use this compiler, concatenate these
499: specs and pass to do_spec. */
500: };
501:
502: /* Pointer to a vector of `struct compiler' that gives the spec for
503: compiling a file, based on its suffix.
504: A file that does not end in any of these suffixes will be passed
505: unchanged to the loader and nothing else will be done to it.
506:
507: An entry containing two 0s is used to terminate the vector.
508:
509: If multiple entries match a file, the last matching one is used. */
510:
511: static struct compiler *compilers;
512:
513: /* Number of entries in `compilers', not counting the null terminator. */
514:
515: static int n_compilers;
516:
517: /* The default list of file name suffixes and their compilation specs. */
518:
519: #ifdef NEXT_FAT_OUTPUT
520: static struct compiler default_compilers[] =
521: {
522: {".m", "@c"},
523: {".c", "@c"},
524: {"@c",
525: "%{@:%{E|M|MM|S:%eCannot use -E, -M, -MM, or -S with multiple architectures}}\
526: %{traditional|traditional-cpp:cpp}%:{cpp-precomp -smart}\
527: %{.c|.m:%BCompiling} \
528: %{.m|ObjC|fobjc:-lang-objc}%:{-lang-c} \
529: %{nostdinc*|C|v|A*|I*|P} %I\
530: %{C:%{!E:%eGNU C does not support -C without using -E}}\
531: -arch %T %{@:-arch_multiple}\
532: %{M|MM} %{MD:-MD %M} %{MMD:-MMD %M}\
533: -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
534: %{ObjC|.m|fobjc:-D__OBJC__} \
535: -D__GNU__ %{precomp|no-precomp}\
536: %{!undef:%{!ansi:%p} %P} %{trigraphs}\
537: %c %{O|O1|O2|O3|O4|O5|O6:-D__OPTIMIZE__}\
538: %{traditional|ftraditional:-traditional}\
539: %{g*|W*|w|pedantic*|H|d*} %C %{D*|U*|i*}\
540: %i %{!M:%{!MM:%{!E:%{!precomp:%{!pipe:%g.i}}}}}\
541: %{E:%W{o}}%{M:%W{o}}%{MM:%W{o}}\
542: %{precomp:%{@:-o %f%g-%T.p}%{!@:%W{o}%W{!o:-o %b.p }} } |\n",
543: "%{!M:%{!MM:%{!E:%{!precomp:cc1obj %{!pipe:%g.i} %1 \
544: -arch %T %{@:-arch_multiple} %{.m|ObjC|fobjc:-fobjc} \
545: %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\
546: %{g*} %{O|O1|O2|O3|O4|O5|O6} %{W*} %{w} %{pedantic*} %{ansi} \
547: %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
548: %{aux-info*} %{k:-fPIC} \
549: %{.m|ObjC|fobjc: %{fgen-decls}}\
550: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
551: %{S:%W{o}%{!o:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
552: %{!S:as %{I*} %{R} %{j} %{J} %{h} %{d2} %a %Y\
553: %{force_cpusubtype_ALL} %{k} \
554: %{NEXTSTEP-deployment-target} \
555: -arch %T %{@:-arch_multiple}\
556: %{@:-o %f%g-%T.o}%{!@: %{c:%W{o}%{!o:-o %w%b.o}}%{!c:-o %d%w%g-%b.o}}\
557: %{!pipe:%g.s} %A\n }}}}}"},
558: {"-",
559: "%{@:%{E:%eCannot use -E with multiple architectures}\
560: %{M:%eCannot use -M with multiple architectures}\
561: %{MM:%eCannot use -MM with multiple architectures}\
562: %{S:%eCannot use -S with multiple architectures}}\
563: %{E:cpp %{ObjC|fobjc:-lang-objc}%:{-lang-c}\
564: %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
565: %{C:%{!E:%eGNU C does not support -C without using -E}}\
566: %{M} %{MM} %{MD:-MD %M} %{MMD:-MMD %M}\
567: -D__GNU__ %{precomp} %{no-precomp}\
568: -undef %{ObjC|fobjc:-D__OBJC__} -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
569: %{!undef:%{!ansi:%p} %P} %{trigraphs}\
570: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
571: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
572: %i %W{o}}\
573: %{!E:%e-E required when input is from standard input}"},
574: {".h", "@c-header"},
575: {"@c-header",
576: "%{@:%{E:%eCannot use -E with multiple architectures}\
577: %{M:%eCannot use -M with multiple architectures}\
578: %{MM:%eCannot use -MM with multiple architectures}\
579: %{S:%eCannot use -S with multiple architectures}}\
580: %{!E:%{!precomp:%eCompilation of header file requested}} \
581: %{.h:%BPrecompiling} \
582: %{traditional|traditional-cpp:cpp}%:{cpp-precomp -smart}\
583: %{!fno-objc:-lang-objc}%:{-lang-c} \
584: %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
585: %{C:%{!E:%eGNU C does not support -C without using -E}}\
586: -arch %T %{@:-arch_multiple}\
587: %{M} %{MM} %{MD:-MD %M} %{MMD:-MMD %M} \
588: -D__GNU__ %{precomp} %{no-precomp}\
589: -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
590: %{ObjC|fobjc:-D__OBJC__} \
591: %{!undef:%{!ansi:%p} %P} %{trigraphs}\
592: %c %{O|O1|O2|O3|O4|O5|O6:-D__OPTIMIZE__}\
593: %{traditional|ftraditional:-traditional}\
594: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
595: %i %{!precomp:%W{o}}%{precomp:%{@:-o %f%g-%T.p}%{!@:%W{o}%W{!o:-o %b.p }} }"},
596: {".cc", "@c++"},
597: {".cxx", "@c++"},
598: {".cpp", "@c++"},
599: {".C", "@c++"},
600: {".M", "@c++"},
601: {".mm", "@c++"},
602: {"@c++",
603: "%{@:%{E:%eCannot use -E with multiple architectures}\
604: %{M:%eCannot use -M with multiple architectures}\
605: %{MM:%eCannot use -MM with multiple architectures}\
606: %{S:%eCannot use -S with multiple architectures}}\
607: cpp %{.M|.mm|ObjC++|fobjc:-lang-objc++}%:{-lang-c++}\
608: %{.cc|.cxx|.cpp|.C|.M|.mm:%BCompiling} \
609: %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
610: %{C:%{!E:%eGNU C++ does not support -C without using -E}}\
611: %{precomp:%ePrecompilation of C++ not supported}\
612: %{M} %{MM} %{MD:-MD %M} %{MMD:-MMD %M}\
613: -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus\
614: %{.M|.mm|ObjC++|fobjc:-D__OBJC__} \
615: %{ansi:-trigraphs -$ -D__STRICT_ANSI__} -D__GNU__ %{!undef:%{!ansi:%p} %P}\
616: %c %{O|O1|O2|O3|O4|O5|O6:-D__OPTIMIZE__}\
617: %{traditional|ftraditional:-traditional}\
618: %{trigraphs}\
619: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
620: %i %{!M:%{!MM:%{!E:%{!precomp:%{!pipe:%g.i}}}}} %{E:%W{o}}%{M:%W{o}}%{MM:%W{o}}\
621: %{precomp:%{@:-o %f%g-%T.p}%{!@:%W{o}%W{!o:-o %b.p }} } |\n",
622: "%{!M:%{!MM:%{!E:%{!precomp:cc1objplus %{!pipe:%g.i} %1\
623: -arch %T %{@:-arch_multiple} %{.M|ObjC++|.mm|fobjc:-fobjc} \
624: %{!Q:-quiet} -dumpbase %b.M %{d*} %{m*} %{a}\
625: %{!g:%{g*}} %{g:-ggdb} %{O|O1|O2|O3|O4|O5|O6}\
626: %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
627: %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
628: %{aux-info*} %{k:-fPIC} \
629: %{.M|ObjC++|fobjc|.mm: %{fgen-decls}} \
630: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
631: %{S:%W{o}%{!o:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
632: %{!S:as %{I*} %{R} %{j} %{J} %{h} %{d2} %a %Y\
633: %{force_cpusubtype_ALL} %{k} -arch %T %{@:-arch_multiple}\
634: %{@:-o %f%g-%T.o}%{!@: %{c:%W{o}%{!o:-o %w%b.o}}%{!c:-o %d%w%g-%b.o}}\
635: %{!pipe:%g.s} %A\n }}}}}"},
636: {".i", "@cpp-output"},
637: {"@cpp-output",
638: "%{@:%{E:%eCannot use -E with multiple architectures}\
639: %{M:%eCannot use -M with multiple architectures}\
640: %{MM:%eCannot use -MM with multiple architectures}\
641: %{S:%eCannot use -S with multiple architectures}}\
642: cc1obj %i %1 \
643: -arch %T %{@:-arch_multiple} %{ObjC|fobjc:-fobjc} \
644: %{!Q:-quiet} %{Y*} %{d*} %{m*} %{a}\
645: %{g*} %{O|O1|O2|O3|O4|O5|O6}\
646: %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
647: %{v:-version} %{pg:-p} %{p} %{f*}\
648: %{aux-info*} %{k:-fPIC} \
649: %{Obj|fobjc: %{fgen-decls}}\
650: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
651: %{S:%W{o}%{!o:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
652: %{!S:as %{I*} %{R} %{j} %{J} %{h} %{d2} %a %Y\
653: %{force_cpusubtype_ALL} %{k} -arch %T %{@:-arch_multiple}\
654: %{@:-o %f%g-%T.o}%{!@: %{c:%W{o}%{!o:-o %w%b.o}}%{!c:-o %d%w%g-%b.o}} %{!pipe:%g.s} %A\n }"},
655: {".ii", "@c++-cpp-output"},
656: {"@c++-cpp-output",
657: "cc1objplus %i %1\
658: -arch %T %{@:-arch_multiple} %{ObjC++|fobjc:-fobjc}\
659: %{!Q:-quiet} %{d*} %{m*} %{a}\
660: %{!g:%{g*}} %{g:-ggdb} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
661: %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
662: %{ObjC++|fobjc: %{fgen-decls}}\
663: %{aux-info*} %{k:-fPIC} \
664: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
665: %{S:%W{o}%{!o:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
666: %{!S:as %{I*} %{R} %{j} %{J} %{h} %{d2} %a %Y\
667: %{force_cpusubtype_ALL} %{k} -arch %T %{@:-arch_multiple}\
668: %{@:-o %f%g-%T.o}%{!@: %{c:%W{o}%{!o:-o %w%b.o}}%{!c:-o %d%w%g-%b.o}}\
669: %{!pipe:%g.s} %A\n }"},
670: {".s", "@assembler-with-cpp"},
671: {".S", "@assembler-with-cpp"},
672: {"@assembler-with-cpp",
673: "%{@:%{E:%eCannot use -E with multiple architectures}\
674: %{M:%eCannot use -M with multiple architectures}\
675: %{MM:%eCannot use -MM with multiple architectures}\
676: %{S:%eCannot use -S with multiple architectures}}\
677: cpp -lang-asm %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
678: %{.s|.S:%BAssembling} \
679: %{C:%{!E:%eGNU C does not support -C without using -E}}\
680: %{M} %{MM} %{MD:-MD %M} %{MMD:-MMD %M} %{trigraphs} \
681: -D__GNU__ %{precomp:%dPrecompilation of assembler not supported}\
682: -undef -$ %{!undef:%p %P} -D__ASSEMBLER__ \
683: %c %{O|O1|O2|O3|O4|O5|O6:-D__OPTIMIZE__}\
684: %{traditional|ftraditional:-traditional}\
685: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
686: %i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o}}%{M:%W{o}}%{MM:%W{o}} |\n",
687: "%{!M:%{!MM:%{!E:%{!S:as %{I*} %{R} %{j} %{J} %{h} %{d2} %a %Y\
688: %{force_cpusubtype_ALL} %{k} -arch %T %{@:-arch_multiple} \
689: %{@:-o %f%g-%T.o}%{!@: %{c:%W{o}%{!o:-o %w%b.o}}%{!c:-o %d%w%g-%b.o}}\
690: %{!pipe:%g.s} %A\n }}}}"},
691: /* Mark end of table */
692: {0, 0}
693: };
694: #else /* not NEXT_FAT_OUTPUT */
695: static struct compiler default_compilers[] =
696: {
697: {".c", "@c"},
698: {"@c",
699: "cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
700: %{C:%{!E:%eGNU C does not support -C without using -E}}\
701: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\
702: -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
703: %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
704: %{!undef:%{!ansi:%p} %P} %{trigraphs} \
705: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
706: %{traditional-cpp:-traditional}\
707: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
708: %i %{!M:%{!MM:%{!E:%{!precomp:%{!pipe:%g.i}}}}}\
709: %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\
710: %{precomp:%{@:-o %f%g-%T.p}%{!@:%W{o}%W{!o:-o %b.p }} } |\n",
711: "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \
712: %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\
713: %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
714: %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
715: %{aux-info*}\
716: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
717: %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
718: %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
719: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
720: %{!pipe:%g.s} %A\n }}}}"},
721: {"-",
722: "%{E:cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
723: %{C:%{!E:%eGNU C does not support -C without using -E}}\
724: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\
725: -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
726: %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
727: %{!undef:%{!ansi:%p} %P} %{trigraphs}\
728: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
729: %{traditional-cpp:-traditional}\
730: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
731: %i %W{o*}}\
732: %{!E:%e-E required when input is from standard input}"},
733: {".m", "@objective-c"},
734: {"=objc", "@objective-c"},
735: {"@objective-c",
736: "cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
737: %{C:%{!E:%eGNU C does not support -C without using -E}}\
738: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\
739: -undef -D__OBJC__ -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
740: %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
741: %{!undef:%{!ansi:%p} %P} %{trigraphs}\
742: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
743: %{traditional-cpp:-traditional}\
744: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
745: %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
746: "%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.i} %1 \
747: %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a}\
748: %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
749: %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \
750: -lang-objc %{fgen-decls} \
751: %{aux-info*} \
752: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
753: %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
754: %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
755: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
756: %{!pipe:%g.s} %A\n }}}}"},
757: {".h", "@c-header"},
758: {"@c-header",
759: "%{!E:%eCompilation of header file requested} \
760: cpp %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
761: %{C:%{!E:%eGNU C does not support -C without using -E}}\
762: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \
763: -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
764: %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
765: %{!undef:%{!ansi:%p} %P} %{trigraphs}\
766: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
767: %{traditional-cpp:-traditional}\
768: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
769: %i %W{o*}"},
770: {".cc", "@c++"},
771: {".cxx", "@c++"},
772: {".C", "@c++"},
773: {"@c++",
774: "cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
775: %{C:%{!E:%eGNU C++ does not support -C without using -E}}\
776: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \
777: -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\
778: %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
779: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
780: %{traditional-cpp:-traditional} %{trigraphs}\
781: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
782: %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
783: "%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.i} %1 %2\
784: %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
785: %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
786: %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
787: %{aux-info*}\
788: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
789: %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
790: %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
791: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
792: %{!pipe:%g.s} %A\n }}}}"},
793: {".M", "@objective-c++"},
794: {".mm", "@objective-c++"},
795: {"=objc++", "@objective-c++"},
796: {"@objective-c++",
797: "cpp -lang-objc++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
798: %{C:%{!E:%eGNU C++ does not support -C without using -E}}\
799: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \
800: -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\
801: %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
802: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
803: %{traditional-cpp:-traditional} %{trigraphs}\
804: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
805: %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
806: "%{!M:%{!MM:%{!E:cc1objplus %{!pipe:%g.i} %1 %2\
807: %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
808: %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
809: %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
810: %{aux-info*}\
811: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
812: %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
813: %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
814: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
815: %{!pipe:%g.s} %A\n }}}}"},
816: {".i", "@cpp-output"},
817: {"@cpp-output",
818: "cc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\
819: %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
820: %{v:-version} %{pg:-p} %{p} %{f*}\
821: %{aux-info*}\
822: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
823: %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
824: %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
825: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %{!pipe:%g.s} %A\n }"},
826: {".ii", "@c++-cpp-output"},
827: {"@c++-cpp-output",
828: "cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
829: %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
830: %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\
831: %{aux-info*}\
832: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
833: %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
834: %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
835: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
836: %{!pipe:%g.s} %A\n }"},
837: {".s", "@assembler"},
838: {"@assembler",
839: "%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
840: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %i %A\n }"},
841: {".S", "@assembler-with-cpp"},
842: {"@assembler-with-cpp",
843: "cpp -lang-asm %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
844: %{C:%{!E:%eGNU C does not support -C without using -E}}\
845: %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{trigraphs} \
846: -undef -$ %{!undef:%p %P} -D__ASSEMBLER__ \
847: %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
848: %{traditional-cpp:-traditional}\
849: %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
850: %i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
851: "%{!M:%{!MM:%{!E:%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
852: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
853: %{!pipe:%g.s} %A\n }}}}"},
854: {".ads", "@ada"},
855: {".adb", "@ada"},
856: {".ada", "@ada"},
857: {"@ada",
858: "gnat1 %{gnat*} %{k8:-gnatk8} %{w:-gnatws}\
859: -dumpbase %b.ada\
860: %{g*} %{O*} %{p} %{pg:-p} %{f*} %{d*}\
861: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
862: %i %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} | \n",
863: "%{!S:%{!gnatc:%{!gnats:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
864: %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
865: %{!pipe:%g.s} %A\n}}} "},
866: /* Mark end of table */
867: {0, 0}
868: };
869: #endif /* not NEXT_FAT_OUTPUT */
870:
871: /* Number of elements in default_compilers, not counting the terminator. */
872:
873: static int n_default_compilers
874: = (sizeof default_compilers / sizeof (struct compiler)) - 1;
875:
876: /* Here is the spec for running the linker, after compiling all files. */
877:
878: /* -u* was put back because both BSD and SysV seem to support it. */
879: /* %{static:} simply prevents an error message if the target machine
880: doesn't handle -static. */
881: /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
882: scripts which exist in user specified directories, or in standard
883: directories. */
884: #ifdef LINK_COMMAND_SPEC
885: static char *link_command_spec = LINK_COMMAND_SPEC;
886: #else
887: #ifdef LINK_LIBGCC_SPECIAL_1
888: /* Have gcc do the search for libgcc.a, but generate -L options as usual. */
889: static char *link_command_spec = "\
890: %{!fsyntax-only: \
891: %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
892: %{r} %{s} %{t} %{u*} %{x} %{z}\
893: %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
894: %{L*} %D %{T*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
895: #else
896: #ifdef LINK_LIBGCC_SPECIAL
897: /* Have gcc do the search for libgcc.a, and don't generate -L options. */
898: static char *link_command_spec = "\
899: %{!fsyntax-only: \
900: %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
901: %{r} %{s} %{t} %{u*} %{x} %{z}\
902: %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
903: %{L*} %{T*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
904: #else
905: /* Use -L and have the linker do the search for -lgcc. */
906: static char *link_command_spec = "\
907: %{!fsyntax-only: \
908: %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
909: %{r} %{s} %{t} %{u*} %{x} %{z}\
910: %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
911: %{L*} %D %{T*} %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}}";
912: #endif
913: #endif
914: #endif
915:
916: #ifdef NEXT_FAT_OUTPUT
917: /* The spec for running the architecture merger. This is run whenever
918: compiling multiple architectures and the output is a .o or an
919: executable. */
920: static char *ofile_merge_spec = "\
921: %{!M:%{!MM:%{!E:%{!precomp:%{!S:lipo -create %F \
922: %{c:%W{o}%{!o:-o %w%b.o}}%{!c:-o %g%w%b.o}\n }}}}}";
923: static char *exec_merge_spec = "\
924: %{!M:%{!MM:%{!E:%{!precomp:%{!S:%{!c:lipo -create %F \
925: %{o}%{!o:-o a.out}\n }}}}}}";
926: static char *precomp_merge_spec = "\
927: %{!M:%{!MM:%{!E:%{precomp:%{!S:%{!c:lipo -create %F \
928: %{o}%{!o:-o %b.p}\n }}}}}}";
929:
930: #endif /* NEXT_FAT_OUTPUT */
931:
932: /* A vector of options to give to the linker.
933: These options are accumulated by -Xlinker and -Wl,
934: and substituted into the linker command with %X. */
935: static int n_linker_options;
936: static char **linker_options;
937:
938: /* A vector of options to give to the assembler.
939: These options are accumulated by -Wa,
940: and substituted into the assembler command with %X. */
941: static int n_assembler_options;
942: static char **assembler_options;
943:
944: /* Define how to map long options into short ones. */
945:
946: /* This structure describes one mapping. */
947: struct option_map
948: {
949: /* The long option's name. */
950: char *name;
951: /* The equivalent short option. */
952: char *equivalent;
953: /* Argument info. A string of flag chars; NULL equals no options.
954: a => argument required.
955: o => argument optional.
956: j => join argument to equivalent, making one word.
957: * => allow other text after NAME as an argument. */
958: char *arg_info;
959: };
960:
961: /* This is the table of mappings. Mappings are tried sequentially
962: for each option encountered; the first one that matches, wins. */
963:
964: struct option_map option_map[] =
965: {
966: {"--profile-blocks", "-a", 0},
967: {"--target", "-b", "a"},
968: {"--compile", "-c", 0},
969: {"--dump", "-d", "a"},
970: {"--entry", "-e", 0},
971: {"--debug", "-g", "oj"},
972: {"--include", "-include", "a"},
973: {"--imacros", "-imacros", "a"},
974: {"--include-prefix", "-iprefix", "a"},
975: {"--include-directory-after", "-idirafter", "a"},
976: {"--include-with-prefix", "-iwithprefix", "a"},
977: {"--include-with-prefix-before", "-iwithprefixbefore", "a"},
978: {"--include-with-prefix-after", "-iwithprefix", "a"},
979: {"--machine-", "-m", "*j"},
980: {"--machine", "-m", "aj"},
981: {"--no-standard-includes", "-nostdinc", 0},
982: {"--no-standard-libraries", "-nostdlib", 0},
983: {"--no-precompiled-includes", "-noprecomp", 0},
984: {"--output", "-o", "a"},
985: {"--profile", "-p", 0},
986: {"--quiet", "-q", 0},
987: {"--silent", "-q", 0},
988: {"--force-link", "-u", "a"},
989: {"--verbose", "-v", 0},
990: {"--version", "-dumpversion", 0},
991: {"--no-warnings", "-w", 0},
992: {"--language", "-x", "a"},
993: {"--default-language", "-X", "a"},
994:
995: {"--assert", "-A", "a"},
996: {"--prefix", "-B", "a"},
997: {"--comments", "-C", 0},
998: {"--define-macro", "-D", "a"},
999: {"--preprocess", "-E", 0},
1000: {"--trace-includes", "-H", 0},
1001: {"--include-directory", "-I", "a"},
1002: {"--include-barrier", "-I-", 0},
1003: {"--library-directory", "-L", "a"},
1004: {"--dependencies", "-M", 0},
1005: {"--user-dependencies", "-MM", 0},
1006: {"--write-dependencies", "-MD", 0},
1007: {"--write-user-dependencies", "-MMD", 0},
1008: {"--optimize", "-O", "oj"},
1009: {"--no-line-commands", "-P", 0},
1010: {"--assemble", "-S", 0},
1011: {"--undefine-macro", "-U", "a"},
1012: {"--use-version", "-V", "a"},
1013: {"--for-assembler", "-Wa", "a"},
1014: {"--extra-warnings", "-W", 0},
1015: {"--all-warnings", "-Wall", 0},
1016: {"--warn-", "-W", "*j"},
1017: {"--for-linker", "-Xlinker", "a"},
1018:
1019: {"--ansi", "-ansi", 0},
1020: {"--traditional", "-traditional", 0},
1021: {"--traditional-cpp", "-traditional-cpp", 0},
1022: {"--trigraphs", "-trigraphs", 0},
1023: {"--pipe", "-pipe", 0},
1024: {"--dumpbase", "-dumpbase", "a"},
1025: {"--pedantic", "-pedantic", 0},
1026: {"--pedantic-errors", "-pedantic-errors", 0},
1027: {"--save-temps", "-save-temps", 0},
1028: {"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
1029: {"--static", "-static", 0},
1030: {"--shared", "-shared", 0},
1031: {"--symbolic", "-symbolic", 0},
1032: {"--", "-f", "*j"}
1033: };
1034:
1035: /* Translate the options described by *ARGCP and *ARGVP.
1036: Make a new vector and store it back in *ARGVP,
1037: and store its length in *ARGVC. */
1038:
1039: static void
1040: translate_options (argcp, argvp)
1041: int *argcp;
1042: char ***argvp;
1043: {
1044: int i, j;
1045: int argc = *argcp;
1046: char **argv = *argvp;
1047: char **newv = (char **) xmalloc ((argc + 2) * 2 * sizeof (char *));
1048: int newindex = 0;
1049:
1050: i = 0;
1051: newv[newindex++] = argv[i++];
1052:
1053: while (i < argc)
1054: {
1055: /* Translate -- options. */
1056: if (argv[i][0] == '-' && argv[i][1] == '-')
1057: {
1058: /* Find a mapping that applies to this option. */
1059: for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++)
1060: {
1061: int optlen = strlen (option_map[j].name);
1062: int complen = strlen (argv[i]);
1063: char *arginfo = option_map[j].arg_info;
1064:
1065: if (arginfo == 0)
1066: arginfo = "";
1067: if (complen > optlen)
1068: complen = optlen;
1069: if (!strncmp (argv[i], option_map[j].name, complen))
1070: {
1071: int extra = strlen (argv[i]) > optlen;
1072: char *arg = 0;
1073:
1074: if (extra)
1075: {
1076: /* If the option has an argument, accept that. */
1077: if (argv[i][optlen] == '=')
1078: arg = argv[i] + optlen + 1;
1079: /* If this mapping allows extra text at end of name,
1080: accept that as "argument". */
1081: else if (index (arginfo, '*') != 0)
1082: arg = argv[i] + optlen;
1083: /* Otherwise, extra text at end means mismatch.
1084: Try other mappings. */
1085: else
1086: continue;
1087: }
1088: else if (index (arginfo, '*') != 0)
1089: error ("Incomplete `%s' option", option_map[j].name);
1090:
1091: /* Handle arguments. */
1092: if (index (arginfo, 'o') != 0)
1093: {
1094: if (arg == 0)
1095: {
1096: if (i + 1 == argc)
1097: error ("Missing argument to `%s' option",
1098: option_map[j].name);
1099: arg = argv[++i];
1100: }
1101: }
1102: else if (index (arginfo, '*') != 0)
1103: ;
1104: else if (index (arginfo, 'a') == 0)
1105: {
1106: if (arg != 0)
1107: error ("Extraneous argument to `%s' option",
1108: option_map[j].name);
1109: arg = 0;
1110: }
1111:
1112: /* Store the translation as one argv elt or as two. */
1113: if (arg != 0 && index (arginfo, 'j') != 0)
1114: newv[newindex++] = concat (option_map[j].equivalent,
1115: arg, "");
1116: else if (arg != 0)
1117: {
1118: newv[newindex++] = option_map[j].equivalent;
1119: newv[newindex++] = arg;
1120: }
1121: else
1122: newv[newindex++] = option_map[j].equivalent;
1123:
1124: break;
1125: }
1126: }
1127: i++;
1128: }
1129: /* Handle old-fashioned options--just copy them through,
1130: with their arguments. */
1131: else if (argv[i][0] == '-')
1132: {
1133: char *p = argv[i] + 1;
1134: int c = *p;
1135: int nskip = 1;
1136:
1137: if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
1138: nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
1139: else if (WORD_SWITCH_TAKES_ARG (p))
1140: nskip += WORD_SWITCH_TAKES_ARG (p);
1141:
1142: while (nskip > 0)
1143: {
1144: newv[newindex++] = argv[i++];
1145: nskip--;
1146: }
1147: }
1148: else
1149: /* Ordinary operands, or +e options. */
1150: newv[newindex++] = argv[i++];
1151: }
1152:
1153: newv[newindex] = 0;
1154:
1155: *argvp = newv;
1156: *argcp = newindex;
1157: }
1158:
1159: /* Read compilation specs from a file named FILENAME,
1160: replacing the default ones.
1161:
1162: A suffix which starts with `*' is a definition for
1163: one of the machine-specific sub-specs. The "suffix" should be
1164: *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc.
1165: The corresponding spec is stored in asm_spec, etc.,
1166: rather than in the `compilers' vector.
1167:
1168: Anything invalid in the file is a fatal error. */
1169:
1170: static void
1171: read_specs (filename)
1172: char *filename;
1173: {
1174: int desc;
1175: struct stat statbuf;
1176: char *buffer;
1177: register char *p;
1178:
1179: if (verbose_flag)
1180: fprintf (stderr, "Reading specs from %s\n", filename);
1181:
1182: /* Open and stat the file. */
1183: desc = open (filename, 0, 0);
1184: if (desc < 0)
1185: pfatal_with_name (filename);
1186: if (stat (filename, &statbuf) < 0)
1187: pfatal_with_name (filename);
1188:
1189: /* Read contents of file into BUFFER. */
1190: buffer = xmalloc ((unsigned) statbuf.st_size + 1);
1191: read (desc, buffer, (unsigned) statbuf.st_size);
1192: buffer[statbuf.st_size] = 0;
1193: close (desc);
1194:
1195: /* Scan BUFFER for specs, putting them in the vector. */
1196: p = buffer;
1197: while (1)
1198: {
1199: char *suffix;
1200: char *spec;
1201: char *in, *out, *p1, *p2;
1202:
1203: /* Advance P in BUFFER to the next nonblank nocomment line. */
1204: p = skip_whitespace (p);
1205: if (*p == 0)
1206: break;
1207:
1208: /* Find the colon that should end the suffix. */
1209: p1 = p;
1210: while (*p1 && *p1 != ':' && *p1 != '\n') p1++;
1211: /* The colon shouldn't be missing. */
1212: if (*p1 != ':')
1213: fatal ("specs file malformed after %d characters", p1 - buffer);
1214: /* Skip back over trailing whitespace. */
1215: p2 = p1;
1216: while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--;
1217: /* Copy the suffix to a string. */
1218: suffix = save_string (p, p2 - p);
1219: /* Find the next line. */
1220: p = skip_whitespace (p1 + 1);
1221: if (p[1] == 0)
1222: fatal ("specs file malformed after %d characters", p - buffer);
1223: p1 = p;
1224: /* Find next blank line. */
1225: while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++;
1226: /* Specs end at the blank line and do not include the newline. */
1227: spec = save_string (p, p1 - p);
1228: p = p1;
1229:
1230: /* Delete backslash-newline sequences from the spec. */
1231: in = spec;
1232: out = spec;
1233: while (*in != 0)
1234: {
1235: if (in[0] == '\\' && in[1] == '\n')
1236: in += 2;
1237: else if (in[0] == '#')
1238: {
1239: while (*in && *in != '\n') in++;
1240: }
1241: else
1242: *out++ = *in++;
1243: }
1244: *out = 0;
1245:
1246: if (suffix[0] == '*')
1247: {
1248: if (! strcmp (suffix, "*link_command"))
1249: link_command_spec = spec;
1250: else
1251: set_spec (suffix + 1, spec);
1252: }
1253: else
1254: {
1255: /* Add this pair to the vector. */
1256: compilers
1257: = ((struct compiler *)
1258: xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler)));
1259: compilers[n_compilers].suffix = suffix;
1260: bzero (compilers[n_compilers].spec,
1261: sizeof compilers[n_compilers].spec);
1262: compilers[n_compilers].spec[0] = spec;
1263: n_compilers++;
1264: bzero (&compilers[n_compilers], sizeof compilers[n_compilers]);
1265: }
1266:
1267: if (*suffix == 0)
1268: link_command_spec = spec;
1269: }
1270:
1271: if (link_command_spec == 0)
1272: fatal ("spec file has no spec for linking");
1273: }
1274:
1275: static char *
1276: skip_whitespace (p)
1277: char *p;
1278: {
1279: while (1)
1280: {
1281: /* A fully-blank line is a delimiter in the SPEC file and shouldn't
1282: be considered whitespace. */
1283: if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
1284: return p + 1;
1285: else if (*p == '\n' || *p == ' ' || *p == '\t')
1286: p++;
1287: else if (*p == '#')
1288: {
1289: while (*p != '\n') p++;
1290: p++;
1291: }
1292: else
1293: break;
1294: }
1295:
1296: return p;
1297: }
1298:
1299: /* Structure to keep track of the specs that have been defined so far. These
1300: are accessed using %(specname) or %[specname] in a compiler or link spec. */
1301:
1302: struct spec_list
1303: {
1304: char *name; /* Name of the spec. */
1305: char *spec; /* The spec itself. */
1306: struct spec_list *next; /* Next spec in linked list. */
1307: };
1308:
1309: /* List of specs that have been defined so far. */
1310:
1311: static struct spec_list *specs = (struct spec_list *) 0;
1312:
1313: /* Change the value of spec NAME to SPEC. If SPEC is empty, then the spec is
1314: removed; If the spec starts with a + then SPEC is added to the end of the
1315: current spec. */
1316:
1317: static void
1318: set_spec (name, spec)
1319: char *name;
1320: char *spec;
1321: {
1322: struct spec_list *sl;
1323: char *old_spec;
1324:
1325: /* See if the spec already exists */
1326: for (sl = specs; sl; sl = sl->next)
1327: if (strcmp (sl->name, name) == 0)
1328: break;
1329:
1330: if (!sl)
1331: {
1332: /* Not found - make it */
1333: sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
1334: sl->name = save_string (name, strlen (name));
1335: sl->spec = save_string ("", 0);
1336: sl->next = specs;
1337: specs = sl;
1338: }
1339:
1340: old_spec = sl->spec;
1341: if (name && spec[0] == '+' && isspace (spec[1]))
1342: sl->spec = concat (old_spec, spec + 1, "");
1343: else
1344: sl->spec = save_string (spec, strlen (spec));
1345:
1346: if (! strcmp (name, "asm"))
1347: asm_spec = sl->spec;
1348: else if (! strcmp (name, "asm_final"))
1349: asm_final_spec = sl->spec;
1350: else if (! strcmp (name, "cc1"))
1351: cc1_spec = sl->spec;
1352: else if (! strcmp (name, "cc1plus"))
1353: cc1plus_spec = sl->spec;
1354: else if (! strcmp (name, "cpp"))
1355: cpp_spec = sl->spec;
1356: else if (! strcmp (name, "endfile"))
1357: endfile_spec = sl->spec;
1358: else if (! strcmp (name, "lib"))
1359: lib_spec = sl->spec;
1360: else if (! strcmp (name, "link"))
1361: link_spec = sl->spec;
1362: else if (! strcmp (name, "predefines"))
1363: cpp_predefines = sl->spec;
1364: else if (! strcmp (name, "signed_char"))
1365: signed_char_spec = sl->spec;
1366: else if (! strcmp (name, "startfile"))
1367: startfile_spec = sl->spec;
1368: else if (! strcmp (name, "switches_need_spaces"))
1369: switches_need_spaces = sl->spec;
1370: else if (! strcmp (name, "cross_compile"))
1371: cross_compile = atoi (sl->spec);
1372: /* Free the old spec */
1373: if (old_spec)
1374: free (old_spec);
1375: }
1376:
1377: /* Accumulate a command (program name and args), and run it. */
1378:
1379: /* Vector of pointers to arguments in the current line of specifications. */
1380:
1381: static char **argbuf;
1382:
1383: /* Number of elements allocated in argbuf. */
1384:
1385: static int argbuf_length;
1386:
1387: /* Number of elements in argbuf currently in use (containing args). */
1388:
1389: static int argbuf_index;
1390:
1391: /* This is the list of suffixes and codes (%g/%u/%U) and the associated
1392: temp file. Used only if MKTEMP_EACH_FILE. */
1393:
1394: static struct temp_name {
1395: char *suffix; /* suffix associated with the code. */
1396: int length; /* strlen (suffix). */
1397: int unique; /* Indicates whether %g or %u/%U was used. */
1398: char *filename; /* associated filename. */
1399: int filename_length; /* strlen (filename). */
1400: struct temp_name *next;
1401: } *temp_names;
1402:
1403: /* Number of commands executed so far. */
1404:
1405: static int execution_count;
1406:
1407: /* Number of commands that exited with a signal. */
1408:
1409: static int signal_count;
1410:
1411: /* Name with which this program was invoked. */
1412:
1413: static char *programname;
1414:
1415: /* Structures to keep track of prefixes to try when looking for files. */
1416:
1417: struct prefix_list
1418: {
1419: char *prefix; /* String to prepend to the path. */
1420: struct prefix_list *next; /* Next in linked list. */
1421: int require_machine_suffix; /* Don't use without machine_suffix. */
1422: /* 2 means try both machine_suffix and just_machine_suffix. */
1423: int *used_flag_ptr; /* 1 if a file was found with this prefix. */
1424: };
1425:
1426: struct path_prefix
1427: {
1428: struct prefix_list *plist; /* List of prefixes to try */
1429: int max_len; /* Max length of a prefix in PLIST */
1430: char *name; /* Name of this list (used in config stuff) */
1431: };
1432:
1433: /* List of prefixes to try when looking for executables. */
1434:
1435: static struct path_prefix exec_prefix = { 0, 0, "exec" };
1436:
1437: /* List of prefixes to try when looking for startup (crt0) files. */
1438:
1439: static struct path_prefix startfile_prefix = { 0, 0, "startfile" };
1440:
1441: /* Suffix to attach to directories searched for commands.
1442: This looks like `MACHINE/VERSION/'. */
1443:
1444: static char *machine_suffix = 0;
1445:
1446: /* Suffix to attach to directories searched for commands.
1447: This is just `MACHINE/'. */
1448:
1449: static char *just_machine_suffix = 0;
1450:
1451: /* Adjusted value of GCC_EXEC_PREFIX envvar. */
1452:
1453: static char *gcc_exec_prefix;
1454:
1455: /* Default prefixes to attach to command names. */
1456:
1457: #ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */
1458: #undef MD_EXEC_PREFIX
1459: #undef MD_STARTFILE_PREFIX
1460: #undef MD_STARTFILE_PREFIX_1
1461: #endif
1462:
1463: #ifndef STANDARD_EXEC_PREFIX
1464: #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
1465: #endif /* !defined STANDARD_EXEC_PREFIX */
1466:
1467: static char *standard_exec_prefix = STANDARD_EXEC_PREFIX;
1468: #ifdef NeXT
1469: static char *standard_exec_prefix_1 = "/usr/local/lib/";
1470: static char *standard_exec_prefix_2 = "/lib/";
1471: #else
1472: static char *standard_exec_prefix_1 = "/usr/lib/gcc/";
1473: #endif /* NeXT */
1474: #ifdef MD_EXEC_PREFIX
1475: static char *md_exec_prefix = MD_EXEC_PREFIX;
1476: #endif
1477:
1478: #ifndef STANDARD_STARTFILE_PREFIX
1479: #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
1480: #endif /* !defined STANDARD_STARTFILE_PREFIX */
1481:
1482: #ifdef MD_STARTFILE_PREFIX
1483: static char *md_startfile_prefix = MD_STARTFILE_PREFIX;
1484: #endif
1485: #ifdef MD_STARTFILE_PREFIX_1
1486: static char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
1487: #endif
1488: static char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
1489: static char *standard_startfile_prefix_1 = "/lib/";
1490: static char *standard_startfile_prefix_2 = "/usr/lib/";
1491:
1492: #ifndef TOOLDIR_BASE_PREFIX
1493: #define TOOLDIR_BASE_PREFIX "/usr/local/"
1494: #endif
1495: static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
1496: static char *tooldir_prefix;
1497:
1498: /* Clear out the vector of arguments (after a command is executed). */
1499:
1500: static void
1501: clear_args ()
1502: {
1503: argbuf_index = 0;
1504: }
1505:
1506: /* Add one argument to the vector at the end.
1507: This is done when a space is seen or at the end of the line.
1508: If DELETE_ALWAYS is nonzero, the arg is a filename
1509: and the file should be deleted eventually.
1510: If DELETE_FAILURE is nonzero, the arg is a filename
1511: and the file should be deleted if this compilation fails. */
1512:
1513: static void
1514: store_arg (arg, delete_always, delete_failure)
1515: char *arg;
1516: int delete_always, delete_failure;
1517: {
1518: if (argbuf_index + 1 == argbuf_length)
1519: {
1520: argbuf = (char **) xrealloc (argbuf, (argbuf_length *= 2) * sizeof (char *));
1521: }
1522:
1523: argbuf[argbuf_index++] = arg;
1524: argbuf[argbuf_index] = 0;
1525:
1526: if (delete_always || delete_failure)
1527: record_temp_file (arg, delete_always, delete_failure);
1528: }
1529:
1530: /* Record the names of temporary files we tell compilers to write,
1531: and delete them at the end of the run. */
1532:
1533: /* This is the common prefix we use to make temp file names.
1534: It is chosen once for each run of this program.
1535: It is substituted into a spec by %g.
1536: Thus, all temp file names contain this prefix.
1537: In practice, all temp file names start with this prefix.
1538:
1539: This prefix comes from the envvar TMPDIR if it is defined;
1540: otherwise, from the P_tmpdir macro if that is defined;
1541: otherwise, in /usr/tmp or /tmp. */
1542:
1543: static char *temp_filename;
1544:
1545: /* Length of the prefix. */
1546:
1547: static int temp_filename_length;
1548:
1549: /* Define the list of temporary files to delete. */
1550:
1551: struct temp_file
1552: {
1553: char *name;
1554: struct temp_file *next;
1555: };
1556:
1557: /* Queue of files to delete on success or failure of compilation. */
1558: static struct temp_file *always_delete_queue;
1559: /* Queue of files to delete on failure of compilation. */
1560: static struct temp_file *failure_delete_queue;
1561:
1562: /* Record FILENAME as a file to be deleted automatically.
1563: ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
1564: otherwise delete it in any case.
1565: FAIL_DELETE nonzero means delete it if a compilation step fails;
1566: otherwise delete it in any case. */
1567:
1568: static void
1569: record_temp_file (filename, always_delete, fail_delete)
1570: char *filename;
1571: int always_delete;
1572: int fail_delete;
1573: {
1574: register char *name;
1575: name = xmalloc (strlen (filename) + 1);
1576: strcpy (name, filename);
1577:
1578: if (always_delete)
1579: {
1580: register struct temp_file *temp;
1581: for (temp = always_delete_queue; temp; temp = temp->next)
1582: if (! strcmp (name, temp->name))
1583: goto already1;
1584: temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
1585: temp->next = always_delete_queue;
1586: temp->name = name;
1587: always_delete_queue = temp;
1588: already1:;
1589: }
1590:
1591: if (fail_delete)
1592: {
1593: register struct temp_file *temp;
1594: for (temp = failure_delete_queue; temp; temp = temp->next)
1595: if (! strcmp (name, temp->name))
1596: goto already2;
1597: temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
1598: temp->next = failure_delete_queue;
1599: temp->name = name;
1600: failure_delete_queue = temp;
1601: already2:;
1602: }
1603: }
1604:
1605: /* Delete all the temporary files whose names we previously recorded. */
1606:
1607: static void
1608: delete_temp_files ()
1609: {
1610: register struct temp_file *temp;
1611:
1612: for (temp = always_delete_queue; temp; temp = temp->next)
1613: {
1614: #ifdef DEBUG
1615: int i;
1616: printf ("Delete %s? (y or n) ", temp->name);
1617: fflush (stdout);
1618: i = getchar ();
1619: if (i != '\n')
1620: while (getchar () != '\n') ;
1621: if (i == 'y' || i == 'Y')
1622: #endif /* DEBUG */
1623: {
1624: struct stat st;
1625: if (stat (temp->name, &st) >= 0)
1626: {
1627: /* Delete only ordinary files. */
1628: if (S_ISREG (st.st_mode))
1629: if (unlink (temp->name) < 0)
1630: if (verbose_flag)
1631: perror_with_name (temp->name);
1632: }
1633: }
1634: }
1635:
1636: always_delete_queue = 0;
1637: }
1638:
1639: /* Delete all the files to be deleted on error. */
1640:
1641: static void
1642: delete_failure_queue ()
1643: {
1644: register struct temp_file *temp;
1645:
1646: for (temp = failure_delete_queue; temp; temp = temp->next)
1647: {
1648: #ifdef DEBUG
1649: int i;
1650: printf ("Delete %s? (y or n) ", temp->name);
1651: fflush (stdout);
1652: i = getchar ();
1653: if (i != '\n')
1654: while (getchar () != '\n') ;
1655: if (i == 'y' || i == 'Y')
1656: #endif /* DEBUG */
1657: {
1658: if (unlink (temp->name) < 0)
1659: if (verbose_flag)
1660: perror_with_name (temp->name);
1661: }
1662: }
1663: }
1664:
1665: static void
1666: clear_failure_queue ()
1667: {
1668: failure_delete_queue = 0;
1669: }
1670:
1671: /* Compute a string to use as the base of all temporary file names.
1672: It is substituted for %g. */
1673:
1674: static char *
1675: choose_temp_base_try (try, base)
1676: char *try;
1677: char *base;
1678: {
1679: char *rv;
1680: if (base)
1681: rv = base;
1682: else if (try == (char *)0)
1683: rv = 0;
1684: else if (access (try, R_OK | W_OK) != 0)
1685: rv = 0;
1686: else
1687: rv = try;
1688: return rv;
1689: }
1690:
1691: static void
1692: choose_temp_base ()
1693: {
1694: char *base = 0;
1695: int len;
1696: #ifdef NeXT
1697: struct timeval tv;
1698: #endif
1699:
1700: base = choose_temp_base_try (getenv ("TMPDIR"), base);
1701: base = choose_temp_base_try (getenv ("TMP"), base);
1702: base = choose_temp_base_try (getenv ("TEMP"), base);
1703:
1704: #ifdef P_tmpdir
1705: base = choose_temp_base_try (P_tmpdir, base);
1706: #endif
1707:
1708: base = choose_temp_base_try ("/usr/tmp", base);
1709: base = choose_temp_base_try ("/tmp", base);
1710:
1711: /* If all else fails, use the current directory! */
1712: if (base == (char *)0)
1713: base = "./";
1714:
1715: len = strlen (base);
1716: #ifdef NeXT
1717: temp_filename = xmalloc (len + sizeof("/ccXXXXXX-XXXXXX") + 1);
1718: #else NeXT
1719: temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
1720: #endif NeXT
1721: strcpy (temp_filename, base);
1722: if (len > 0 && temp_filename[len-1] != '/')
1723: temp_filename[len++] = '/';
1724: #ifdef NeXT
1725: gettimeofday (&tv, (struct timezone *)0);
1726: sprintf (temp_filename + len, "cc%06d-XXXXXX", (int) tv.tv_usec);
1727: #else NeXT
1728: strcpy (temp_filename + len, "ccXXXXXX");
1729: #endif NeXT
1730:
1731: mktemp (temp_filename);
1732: temp_filename_length = strlen (temp_filename);
1733: if (temp_filename_length == 0)
1734: abort ();
1735: }
1736:
1737:
1738: /* Routine to add variables to the environment. We do this to pass
1739: the pathname of the gcc driver, and the directories search to the
1740: collect2 program, which is being run as ld. This way, we can be
1741: sure of executing the right compiler when collect2 wants to build
1742: constructors and destructors. Since the environment variables we
1743: use come from an obstack, we don't have to worry about allocating
1744: space for them. */
1745:
1746: #ifndef HAVE_PUTENV
1747:
1748: void
1749: putenv (str)
1750: char *str;
1751: {
1752: #ifndef VMS /* nor about VMS */
1753:
1754: extern char **environ;
1755: char **old_environ = environ;
1756: char **envp;
1757: int num_envs = 0;
1758: int name_len = 1;
1759: int str_len = strlen (str);
1760: char *p = str;
1761: int ch;
1762:
1763: while ((ch = *p++) != '\0' && ch != '=')
1764: name_len++;
1765:
1766: if (!ch)
1767: abort ();
1768:
1769: /* Search for replacing an existing environment variable, and
1770: count the number of total environment variables. */
1771: for (envp = old_environ; *envp; envp++)
1772: {
1773: num_envs++;
1774: if (!strncmp (str, *envp, name_len))
1775: {
1776: *envp = str;
1777: return;
1778: }
1779: }
1780:
1781: /* Add a new environment variable */
1782: environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
1783: *environ = str;
1784: bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));
1785:
1786: #endif /* VMS */
1787: }
1788:
1789: #endif /* HAVE_PUTENV */
1790:
1791:
1792: /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */
1793:
1794: static void
1795: putenv_from_prefixes (paths, env_var)
1796: struct path_prefix *paths;
1797: char *env_var;
1798: {
1799: int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
1800: int just_suffix_len
1801: = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
1802: int first_time = TRUE;
1803: struct prefix_list *pprefix;
1804:
1805: obstack_grow (&collect_obstack, env_var, strlen (env_var));
1806:
1807: for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
1808: {
1809: int len = strlen (pprefix->prefix);
1810:
1811: if (machine_suffix
1812: && is_directory (pprefix->prefix, machine_suffix, 0))
1813: {
1814: if (!first_time)
1815: obstack_1grow (&collect_obstack, PATH_SEPARATOR);
1816:
1817: first_time = FALSE;
1818: obstack_grow (&collect_obstack, pprefix->prefix, len);
1819: obstack_grow (&collect_obstack, machine_suffix, suffix_len);
1820: }
1821:
1822: if (just_machine_suffix
1823: && pprefix->require_machine_suffix == 2
1824: && is_directory (pprefix->prefix, just_machine_suffix, 0))
1825: {
1826: if (!first_time)
1827: obstack_1grow (&collect_obstack, PATH_SEPARATOR);
1828:
1829: first_time = FALSE;
1830: obstack_grow (&collect_obstack, pprefix->prefix, len);
1831: obstack_grow (&collect_obstack, just_machine_suffix,
1832: just_suffix_len);
1833: }
1834:
1835: if (!pprefix->require_machine_suffix)
1836: {
1837: if (!first_time)
1838: obstack_1grow (&collect_obstack, PATH_SEPARATOR);
1839:
1840: first_time = FALSE;
1841: obstack_grow (&collect_obstack, pprefix->prefix, len);
1842: }
1843: }
1844: obstack_1grow (&collect_obstack, '\0');
1845: putenv (obstack_finish (&collect_obstack));
1846: }
1847:
1848:
1849: #ifdef NEXT_CPP_PRECOMP
1850: /* This code is dublicated from below because it is needed in between */
1851:
1852: struct switchstr
1853: {
1854: char *part1;
1855: char **args;
1856: int valid;
1857: };
1858:
1859: static struct switchstr *switches;
1860:
1861: static int n_switches;
1862:
1863: struct infile
1864: {
1865: char *name;
1866: char *language;
1867: };
1868: #endif /* NEXT_CPP_PRECOMP */
1869:
1870: /* Search for NAME using the prefix list PREFIXES. MODE is passed to
1871: access to check permissions.
1872: Return 0 if not found, otherwise return its name, allocated with malloc. */
1873:
1874: static char *
1875: find_a_file (pprefix, name, mode)
1876: struct path_prefix *pprefix;
1877: char *name;
1878: int mode;
1879: {
1880: char *temp;
1881: char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : "");
1882: struct prefix_list *pl;
1883: int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
1884:
1885: if (machine_suffix)
1886: len += strlen (machine_suffix);
1887:
1888: temp = xmalloc (len);
1889:
1890: /* Determine the filename to execute (special case for absolute paths). */
1891:
1892: if (*name == '/')
1893: {
1894: if (access (name, mode))
1895: {
1896: strcpy (temp, name);
1897: return temp;
1898: }
1899: }
1900: else
1901: for (pl = pprefix->plist; pl; pl = pl->next)
1902: {
1903: if (machine_suffix)
1904: {
1905: strcpy (temp, pl->prefix);
1906: strcat (temp, machine_suffix);
1907: strcat (temp, name);
1908: if (access (temp, mode) == 0)
1909: {
1910: if (pl->used_flag_ptr != 0)
1911: *pl->used_flag_ptr = 1;
1912: return temp;
1913: }
1914: /* Some systems have a suffix for executable files.
1915: So try appending that. */
1916: if (file_suffix[0] != 0)
1917: {
1918: strcat (temp, file_suffix);
1919: if (access (temp, mode) == 0)
1920: {
1921: if (pl->used_flag_ptr != 0)
1922: *pl->used_flag_ptr = 1;
1923: return temp;
1924: }
1925: }
1926: }
1927: /* Certain prefixes are tried with just the machine type,
1928: not the version. This is used for finding as, ld, etc. */
1929: if (just_machine_suffix && pl->require_machine_suffix == 2)
1930: {
1931: strcpy (temp, pl->prefix);
1932: strcat (temp, just_machine_suffix);
1933: strcat (temp, name);
1934: if (access (temp, mode) == 0)
1935: {
1936: if (pl->used_flag_ptr != 0)
1937: *pl->used_flag_ptr = 1;
1938: return temp;
1939: }
1940: /* Some systems have a suffix for executable files.
1941: So try appending that. */
1942: if (file_suffix[0] != 0)
1943: {
1944: strcat (temp, file_suffix);
1945: if (access (temp, mode) == 0)
1946: {
1947: if (pl->used_flag_ptr != 0)
1948: *pl->used_flag_ptr = 1;
1949: return temp;
1950: }
1951: }
1952: }
1953: /* Certain prefixes can't be used without the machine suffix
1954: when the machine or version is explicitly specified. */
1955: if (!pl->require_machine_suffix)
1956: {
1957: strcpy (temp, pl->prefix);
1958: strcat (temp, name);
1959: if (access (temp, mode) == 0)
1960: {
1961: if (pl->used_flag_ptr != 0)
1962: *pl->used_flag_ptr = 1;
1963: return temp;
1964: }
1965: /* Some systems have a suffix for executable files.
1966: So try appending that. */
1967: if (file_suffix[0] != 0)
1968: {
1969: strcat (temp, file_suffix);
1970: if (access (temp, mode) == 0)
1971: {
1972: if (pl->used_flag_ptr != 0)
1973: *pl->used_flag_ptr = 1;
1974: return temp;
1975: }
1976: }
1977: }
1978: }
1979:
1980: #ifdef NEXT_CPP_PRECOMP
1981: /* if there is no cpp-precomp and -precomp is not given, use GNU cpp */
1982: if (strcmp(name, "cpp-precomp") == 0)
1983: {
1984: int i = 0;
1985: while (i < n_switches
1986: && (switches[i].part1[0] != 'p'
1987: || strcmp (switches[i].part1, "precomp")))
1988: i++;
1989: if (i == n_switches)
1990: return find_a_file (pprefix, "cpp", mode);
1991: }
1992: #endif /* NEXT_CPP_PRECOMP */
1993:
1994: free (temp);
1995: return 0;
1996: }
1997:
1998: /* Add an entry for PREFIX in PLIST. If FIRST is set, it goes
1999: at the start of the list, otherwise it goes at the end.
2000:
2001: If WARN is nonzero, we will warn if no file is found
2002: through this prefix. WARN should point to an int
2003: which will be set to 1 if this entry is used.
2004:
2005: REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
2006: the complete value of machine_suffix.
2007: 2 means try both machine_suffix and just_machine_suffix. */
2008:
2009: static void
2010: add_prefix (pprefix, prefix, first, require_machine_suffix, warn)
2011: struct path_prefix *pprefix;
2012: char *prefix;
2013: int first;
2014: int require_machine_suffix;
2015: int *warn;
2016: {
2017: struct prefix_list *pl, **prev;
2018: int len;
2019:
2020: if (!first && pprefix->plist)
2021: {
2022: for (pl = pprefix->plist; pl->next; pl = pl->next)
2023: ;
2024: prev = &pl->next;
2025: }
2026: else
2027: prev = &pprefix->plist;
2028:
2029: /* Keep track of the longest prefix */
2030:
2031: len = strlen (prefix);
2032: if (len > pprefix->max_len)
2033: pprefix->max_len = len;
2034:
2035: pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
2036: pl->prefix = save_string (prefix, len);
2037: pl->require_machine_suffix = require_machine_suffix;
2038: pl->used_flag_ptr = warn;
2039: if (warn)
2040: *warn = 0;
2041:
2042: if (*prev)
2043: pl->next = *prev;
2044: else
2045: pl->next = (struct prefix_list *) 0;
2046: *prev = pl;
2047: }
2048:
2049: /* Print warnings for any prefixes in the list PPREFIX that were not used. */
2050:
2051: static void
2052: unused_prefix_warnings (pprefix)
2053: struct path_prefix *pprefix;
2054: {
2055: struct prefix_list *pl = pprefix->plist;
2056:
2057: while (pl)
2058: {
2059: if (pl->used_flag_ptr != 0 && !*pl->used_flag_ptr)
2060: {
2061: error ("file path prefix `%s' never used",
2062: pl->prefix);
2063: /* Prevent duplicate warnings. */
2064: *pl->used_flag_ptr = 1;
2065: }
2066: pl = pl->next;
2067: }
2068: }
2069:
2070: /* Get rid of all prefixes built up so far in *PLISTP. */
2071:
2072: static void
2073: free_path_prefix (pprefix)
2074: struct path_prefix *pprefix;
2075: {
2076: struct prefix_list *pl = pprefix->plist;
2077: struct prefix_list *temp;
2078:
2079: while (pl)
2080: {
2081: temp = pl;
2082: pl = pl->next;
2083: free (temp->prefix);
2084: free ((char *) temp);
2085: }
2086: pprefix->plist = (struct prefix_list *) 0;
2087: }
2088:
2089: /* stdin file number. */
2090: #define STDIN_FILE_NO 0
2091:
2092: /* stdout file number. */
2093: #define STDOUT_FILE_NO 1
2094:
2095: /* value of `pipe': port index for reading. */
2096: #define READ_PORT 0
2097:
2098: /* value of `pipe': port index for writing. */
2099: #define WRITE_PORT 1
2100:
2101: /* Pipe waiting from last process, to be used as input for the next one.
2102: Value is STDIN_FILE_NO if no pipe is waiting
2103: (i.e. the next command is the first of a group). */
2104:
2105: static int last_pipe_input;
2106:
2107: /* Fork one piped subcommand. FUNC is the system call to use
2108: (either execv or execvp). ARGV is the arg vector to use.
2109: NOT_LAST is nonzero if this is not the last subcommand
2110: (i.e. its output should be piped to the next one.) */
2111:
2112: #ifndef OS2
2113: #ifdef __MSDOS__
2114:
2115: /* Declare these to avoid compilation error. They won't be called. */
2116: int execv(const char *a, const char **b){}
2117: int execvp(const char *a, const char **b){}
2118:
2119: static int
2120: pexecute (search_flag, program, argv, not_last)
2121: int search_flag;
2122: char *program;
2123: char *argv[];
2124: int not_last;
2125: {
2126: char *scmd, *rf;
2127: FILE *argfile;
2128: int i, el = search_flag ? 0 : 4;
2129:
2130: scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 6 + el);
2131: rf = scmd + strlen(program) + 2 + el;
2132: sprintf (scmd, "%s%s @%s.gp", program,
2133: (search_flag ? "" : ".exe"), temp_filename);
2134: argfile = fopen (rf, "w");
2135: if (argfile == 0)
2136: pfatal_with_name (rf);
2137:
2138: for (i=1; argv[i]; i++)
2139: {
2140: char *cp;
2141: for (cp = argv[i]; *cp; cp++)
2142: {
2143: if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
2144: fputc ('\\', argfile);
2145: fputc (*cp, argfile);
2146: }
2147: fputc ('\n', argfile);
2148: }
2149: fclose (argfile);
2150:
2151: i = system (scmd);
2152:
2153: remove (rf);
2154:
2155: if (i == -1)
2156: {
2157: perror_exec (program);
2158: return MIN_FATAL_STATUS << 8;
2159: }
2160:
2161: return i << 8;
2162: }
2163:
2164: #else /* not __MSDOS__ */
2165:
2166: static int
2167: pexecute (search_flag, program, argv, not_last)
2168: int search_flag;
2169: char *program;
2170: char *argv[];
2171: int not_last;
2172: {
2173: int (*func)() = (search_flag ? execv : execvp);
2174: int pid;
2175: int pdes[2];
2176: int input_desc = last_pipe_input;
2177: int output_desc = STDOUT_FILE_NO;
2178: int retries, sleep_interval;
2179:
2180: /* If this isn't the last process, make a pipe for its output,
2181: and record it as waiting to be the input to the next process. */
2182:
2183: if (not_last)
2184: {
2185: if (pipe (pdes) < 0)
2186: pfatal_with_name ("pipe");
2187: output_desc = pdes[WRITE_PORT];
2188: last_pipe_input = pdes[READ_PORT];
2189: }
2190: else
2191: last_pipe_input = STDIN_FILE_NO;
2192:
2193: /* Fork a subprocess; wait and retry if it fails. */
2194: sleep_interval = 1;
2195: for (retries = 0; retries < 4; retries++)
2196: {
2197: pid = vfork ();
2198: if (pid >= 0)
2199: break;
2200: sleep (sleep_interval);
2201: sleep_interval *= 2;
2202: }
2203:
2204: switch (pid)
2205: {
2206: case -1:
2207: #ifdef vfork
2208: pfatal_with_name ("fork");
2209: #else
2210: pfatal_with_name ("vfork");
2211: #endif
2212: /* NOTREACHED */
2213: return 0;
2214:
2215: case 0: /* child */
2216: /* Move the input and output pipes into place, if nec. */
2217: if (input_desc != STDIN_FILE_NO)
2218: {
2219: close (STDIN_FILE_NO);
2220: dup (input_desc);
2221: close (input_desc);
2222: }
2223: if (output_desc != STDOUT_FILE_NO)
2224: {
2225: close (STDOUT_FILE_NO);
2226: dup (output_desc);
2227: close (output_desc);
2228: }
2229:
2230: /* Close the parent's descs that aren't wanted here. */
2231: if (last_pipe_input != STDIN_FILE_NO)
2232: close (last_pipe_input);
2233:
2234: /* Exec the program. */
2235: (*func) (program, argv);
2236: perror_exec (program);
2237: exit (-1);
2238: /* NOTREACHED */
2239: return 0;
2240:
2241: default:
2242: /* In the parent, after forking.
2243: Close the descriptors that we made for this child. */
2244: if (input_desc != STDIN_FILE_NO)
2245: close (input_desc);
2246: if (output_desc != STDOUT_FILE_NO)
2247: close (output_desc);
2248:
2249: /* Return child's process number. */
2250: return pid;
2251: }
2252: }
2253:
2254: #endif /* not __MSDOS__ */
2255: #else /* not OS2 */
2256:
2257: static int
2258: pexecute (search_flag, program, argv, not_last)
2259: int search_flag;
2260: char *program;
2261: char *argv[];
2262: int not_last;
2263: {
2264: return (search_flag ? spawnv : spawnvp) (1, program, argv);
2265: }
2266: #endif /* not OS2 */
2267:
2268: /* Return a string similar to ARG except that all shell meta-characters
2269: are escaped. Currently, this only escapes ". This allows one to use
2270: the -v command invocation output as a command line for invoking the
2271: given program. */
2272:
2273: static char *
2274: escape_string (arg)
2275: char * arg;
2276: {
2277: struct obstack result;
2278: char * resultptr, * argptr;
2279:
2280: if (!strchr (arg,'"') && !strchr (arg, '(') && !strchr (arg, ')'))
2281: return arg;
2282: else {
2283: obstack_init (&result);
2284: for (argptr = arg; *argptr; argptr++)
2285: {
2286: if (*argptr == '"' || *argptr == '(' || *argptr == ')')
2287: obstack_1grow (&result, '\\');
2288:
2289: obstack_1grow (&result, *argptr);
2290: }
2291: obstack_1grow (&result, '\0');
2292: return obstack_base (&result);
2293: }
2294: }
2295:
2296: /* Execute the command specified by the arguments on the current line of spec.
2297: When using pipes, this includes several piped-together commands
2298: with `|' between them.
2299:
2300: Return 0 if successful, -1 if failed. */
2301:
2302: static int
2303: execute ()
2304: {
2305: int i;
2306: int n_commands; /* # of command. */
2307: char *string;
2308: struct command
2309: {
2310: char *prog; /* program name. */
2311: char **argv; /* vector of args. */
2312: int pid; /* pid of process for this command. */
2313: };
2314:
2315: struct command *commands; /* each command buffer with above info. */
2316:
2317: /* Count # of piped commands. */
2318: for (n_commands = 1, i = 0; i < argbuf_index; i++)
2319: if (strcmp (argbuf[i], "|") == 0)
2320: n_commands++;
2321:
2322: /* Get storage for each command. */
2323: commands
2324: = (struct command *) alloca (n_commands * sizeof (struct command));
2325:
2326: /* Split argbuf into its separate piped processes,
2327: and record info about each one.
2328: Also search for the programs that are to be run. */
2329:
2330: commands[0].prog = argbuf[0]; /* first command. */
2331: commands[0].argv = &argbuf[0];
2332: string = find_a_file (&exec_prefix, commands[0].prog, X_OK);
2333: if (string)
2334: commands[0].argv[0] = string;
2335:
2336: for (n_commands = 1, i = 0; i < argbuf_index; i++)
2337: if (strcmp (argbuf[i], "|") == 0)
2338: { /* each command. */
2339: #ifdef __MSDOS__
2340: fatal ("-pipe not supported under MS-DOS");
2341: #endif
2342: argbuf[i] = 0; /* termination of command args. */
2343: commands[n_commands].prog = argbuf[i + 1];
2344: commands[n_commands].argv = &argbuf[i + 1];
2345: string = find_a_file (&exec_prefix, commands[n_commands].prog, X_OK);
2346: if (string)
2347: commands[n_commands].argv[0] = string;
2348: n_commands++;
2349: }
2350:
2351: argbuf[argbuf_index] = 0;
2352:
2353: /* If -v, print what we are about to do, and maybe query. */
2354:
2355: if (verbose_flag)
2356: {
2357: /* Print each piped command as a separate line. */
2358: for (i = 0; i < n_commands ; i++)
2359: {
2360: char **j;
2361:
2362: for (j = commands[i].argv; *j; j++)
2363: fprintf (stderr, " %s", escape_string (*j));
2364:
2365: /* Print a pipe symbol after all but the last command. */
2366: if (i + 1 != n_commands)
2367: fprintf (stderr, " |");
2368: fprintf (stderr, "\n");
2369: }
2370: fflush (stderr);
2371: #ifdef DEBUG
2372: fprintf (stderr, "\nGo ahead? (y or n) ");
2373: fflush (stderr);
2374: i = getchar ();
2375: if (i != '\n')
2376: while (getchar () != '\n') ;
2377: if (i != 'y' && i != 'Y')
2378: return 0;
2379: #endif /* DEBUG */
2380: }
2381:
2382: DO_REPORT_EVENT ();
2383:
2384: /* Run each piped subprocess. */
2385:
2386: last_pipe_input = STDIN_FILE_NO;
2387: for (i = 0; i < n_commands; i++)
2388: {
2389: char *string = commands[i].argv[0];
2390:
2391: commands[i].pid = pexecute (string != commands[i].prog,
2392: string, commands[i].argv,
2393: i + 1 < n_commands);
2394:
2395: if (string != commands[i].prog)
2396: free (string);
2397: }
2398:
2399: execution_count++;
2400:
2401: /* Wait for all the subprocesses to finish.
2402: We don't care what order they finish in;
2403: we know that N_COMMANDS waits will get them all. */
2404:
2405: {
2406: int ret_code = 0;
2407:
2408: for (i = 0; i < n_commands; i++)
2409: {
2410: int status;
2411: int pid;
2412: char *prog;
2413:
2414: #ifdef __MSDOS__
2415: status = pid = commands[i].pid;
2416: #else
2417: pid = wait (&status);
2418: #endif
2419: if (pid < 0)
2420: abort ();
2421:
2422: if (status != 0)
2423: {
2424: int j;
2425: for (j = 0; j < n_commands; j++)
2426: if (commands[j].pid == pid)
2427: prog = commands[j].prog;
2428:
2429: if ((status & 0x7F) != 0)
2430: {
2431: fatal ("Internal compiler error: program %s got fatal signal %d",
2432: prog, (status & 0x7F));
2433: signal_count++;
2434: }
2435: if (((status & 0xFF00) >> 8) >= MIN_FATAL_STATUS)
2436: ret_code = -1;
2437: }
2438: }
2439: return ret_code;
2440: }
2441: }
2442:
2443: #ifndef NEXT_CPP_PRECOMP
2444: /* Find all the switches given to us
2445: and make a vector describing them.
2446: The elements of the vector are strings, one per switch given.
2447: If a switch uses following arguments, then the `part1' field
2448: is the switch itself and the `args' field
2449: is a null-terminated vector containing the following arguments.
2450: The `valid' field is nonzero if any spec has looked at this switch;
2451: if it remains zero at the end of the run, it must be meaningless. */
2452:
2453: struct switchstr
2454: {
2455: char *part1;
2456: char **args;
2457: int valid;
2458: };
2459:
2460: static struct switchstr *switches;
2461:
2462: static int n_switches;
2463:
2464: struct infile
2465: {
2466: char *name;
2467: char *language;
2468: };
2469: #endif /* not NEXT_CPP_PRECOMP */
2470:
2471: /* Also a vector of input files specified. */
2472:
2473: static struct infile *infiles;
2474:
2475: static int n_infiles;
2476:
2477: /* And a vector of corresponding output files is made up later. */
2478:
2479: static char **outfiles;
2480:
2481: #ifdef NEXT_FAT_OUTPUT
2482: /* A vector of per-architecture files to be merged together. */
2483:
2484: char **arch_merge_files;
2485:
2486: /* The dependency output file (specified with -dependency-file) */
2487:
2488: static char *dependency_output_file = NULL;
2489:
2490: #endif /* NEXT_FAT_OUTPUT */
2491:
2492: /* The default language is the argument of the -X flag to gcc.
2493: "-X language" is like "-x language" except it applies for all
2494: files on the command line, even appearing before the option.
2495: Also, -xnone resets language to the default given by -X.
2496:
2497: gcc file0.c -xc++ file1.c -xnone file2.c -xobjc++ file3.c -Xobjc
2498:
2499: file0.c -- compiled with default objc
2500: file1.c -- compiles with c++
2501: file2.c -- compiles as objc
2502: file3.c -- compiles as objc++
2503: */
2504: static char *default_language = NULL;
2505:
2506: /* Create the vector `switches' and its contents.
2507: Store its length in `n_switches'. */
2508:
2509: static void
2510: process_command (argc, argv)
2511: int argc;
2512: char **argv;
2513: {
2514: register int i;
2515: char *temp;
2516: char *spec_lang = 0;
2517: int last_language_n_infiles;
2518:
2519: gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX");
2520:
2521: n_switches = 0;
2522: n_infiles = 0;
2523:
2524: /* Default for -V is our version number, ending at first space. */
2525: spec_version = save_string (version_string, strlen (version_string));
2526: for (temp = spec_version; *temp && *temp != ' '; temp++);
2527: if (*temp) *temp = '\0';
2528:
2529: /* Set up the default search paths. */
2530:
2531: if (gcc_exec_prefix)
2532: {
2533: add_prefix (&exec_prefix, gcc_exec_prefix, 0, 0, NULL_PTR);
2534: add_prefix (&startfile_prefix, gcc_exec_prefix, 0, 0, NULL_PTR);
2535: }
2536:
2537: /* COMPILER_PATH and LIBRARY_PATH have values
2538: that are lists of directory names with colons. */
2539:
2540: temp = getenv ("COMPILER_PATH");
2541: if (temp)
2542: {
2543: char *startp, *endp;
2544: char *nstore = (char *) alloca (strlen (temp) + 3);
2545:
2546: startp = endp = temp;
2547: while (1)
2548: {
2549: if (*endp == PATH_SEPARATOR || *endp == 0)
2550: {
2551: strncpy (nstore, startp, endp-startp);
2552: if (endp == startp)
2553: {
2554: strcpy (nstore, "./");
2555: }
2556: else if (endp[-1] != '/')
2557: {
2558: nstore[endp-startp] = '/';
2559: nstore[endp-startp+1] = 0;
2560: }
2561: else
2562: nstore[endp-startp] = 0;
2563: add_prefix (&exec_prefix, nstore, 0, 0, NULL_PTR);
2564: if (*endp == 0)
2565: break;
2566: endp = startp = endp + 1;
2567: }
2568: else
2569: endp++;
2570: }
2571: }
2572:
2573: temp = getenv ("LIBRARY_PATH");
2574: if (temp)
2575: {
2576: char *startp, *endp;
2577: char *nstore = (char *) alloca (strlen (temp) + 3);
2578:
2579: startp = endp = temp;
2580: while (1)
2581: {
2582: if (*endp == PATH_SEPARATOR || *endp == 0)
2583: {
2584: strncpy (nstore, startp, endp-startp);
2585: if (endp == startp)
2586: {
2587: strcpy (nstore, "./");
2588: }
2589: else if (endp[-1] != '/')
2590: {
2591: nstore[endp-startp] = '/';
2592: nstore[endp-startp+1] = 0;
2593: }
2594: else
2595: nstore[endp-startp] = 0;
2596: add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR);
2597: if (*endp == 0)
2598: break;
2599: endp = startp = endp + 1;
2600: }
2601: else
2602: endp++;
2603: }
2604: }
2605:
2606: /* Use LPATH like LIBRARY_PATH (for the CMU build program). */
2607: temp = getenv ("LPATH");
2608: if (temp)
2609: {
2610: char *startp, *endp;
2611: char *nstore = (char *) alloca (strlen (temp) + 3);
2612:
2613: startp = endp = temp;
2614: while (1)
2615: {
2616: if (*endp == PATH_SEPARATOR || *endp == 0)
2617: {
2618: strncpy (nstore, startp, endp-startp);
2619: if (endp == startp)
2620: {
2621: strcpy (nstore, "./");
2622: }
2623: else if (endp[-1] != '/')
2624: {
2625: nstore[endp-startp] = '/';
2626: nstore[endp-startp+1] = 0;
2627: }
2628: else
2629: nstore[endp-startp] = 0;
2630: add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR);
2631: if (*endp == 0)
2632: break;
2633: endp = startp = endp + 1;
2634: }
2635: else
2636: endp++;
2637: }
2638: }
2639:
2640: /* Convert new-style -- options to old-style. */
2641: translate_options (&argc, &argv);
2642:
2643: /* Scan argv twice. Here, the first time, just count how many switches
2644: there will be in their vector, and how many input files in theirs.
2645: Here we also parse the switches that cc itself uses (e.g. -v). */
2646:
2647: for (i = 1; i < argc; i++)
2648: {
2649: if (! strcmp (argv[i], "-dumpspecs"))
2650: {
2651: dump_specs = 1;
2652: }
2653: else if (! strcmp (argv[i], "-dumpversion"))
2654: {
2655: printf ("%s\n", version_string);
2656: exit (0);
2657: }
2658: else if (! strcmp (argv[i], "-print-libgcc-file-name"))
2659: {
2660: print_libgcc_file_name = 1;
2661: }
2662: else if (! strcmp (argv[i], "-Xlinker"))
2663: {
2664: /* Pass the argument of this option to the linker when we link. */
2665:
2666: if (i + 1 == argc)
2667: fatal ("argument to `-Xlinker' is missing");
2668:
2669: n_linker_options++;
2670: if (!linker_options)
2671: linker_options
2672: = (char **) xmalloc (n_linker_options * sizeof (char **));
2673: else
2674: linker_options
2675: = (char **) xrealloc (linker_options,
2676: n_linker_options * sizeof (char **));
2677:
2678: linker_options[n_linker_options - 1] = argv[++i];
2679: }
2680: else if (! strncmp (argv[i], "-Wl,", 4))
2681: {
2682: int prev, j;
2683: /* Pass the rest of this option to the linker when we link. */
2684:
2685: n_linker_options++;
2686: if (!linker_options)
2687: linker_options
2688: = (char **) xmalloc (n_linker_options * sizeof (char **));
2689: else
2690: linker_options
2691: = (char **) xrealloc (linker_options,
2692: n_linker_options * sizeof (char **));
2693:
2694: /* Split the argument at commas. */
2695: prev = 4;
2696: for (j = 4; argv[i][j]; j++)
2697: if (argv[i][j] == ',')
2698: {
2699: linker_options[n_linker_options - 1]
2700: = save_string (argv[i] + prev, j - prev);
2701: n_linker_options++;
2702: linker_options
2703: = (char **) xrealloc (linker_options,
2704: n_linker_options * sizeof (char **));
2705: prev = j + 1;
2706: }
2707: /* Record the part after the last comma. */
2708: linker_options[n_linker_options - 1] = argv[i] + prev;
2709: }
2710: else if (! strncmp (argv[i], "-Wa,", 4))
2711: {
2712: int prev, j;
2713: /* Pass the rest of this option to the assembler. */
2714:
2715: n_assembler_options++;
2716: if (!assembler_options)
2717: assembler_options
2718: = (char **) xmalloc (n_assembler_options * sizeof (char **));
2719: else
2720: assembler_options
2721: = (char **) xrealloc (assembler_options,
2722: n_assembler_options * sizeof (char **));
2723:
2724: /* Split the argument at commas. */
2725: prev = 4;
2726: for (j = 4; argv[i][j]; j++)
2727: if (argv[i][j] == ',')
2728: {
2729: assembler_options[n_assembler_options - 1]
2730: = save_string (argv[i] + prev, j - prev);
2731: n_assembler_options++;
2732: assembler_options
2733: = (char **) xrealloc (assembler_options,
2734: n_assembler_options * sizeof (char **));
2735: prev = j + 1;
2736: }
2737: /* Record the part after the last comma. */
2738: assembler_options[n_assembler_options - 1] = argv[i] + prev;
2739: }
2740: else if (argv[i][0] == '+' && argv[i][1] == 'e')
2741: /* The +e options to the C++ front-end. */
2742: n_switches++;
2743: else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l')
2744: {
2745: register char *p = &argv[i][1];
2746: register int c = *p;
2747:
2748: switch (c)
2749: {
2750: case 'b':
2751: if (p[1] == 0 && i + 1 == argc)
2752: fatal ("argument to `-b' is missing");
2753: if (p[1] == 0)
2754: spec_machine = argv[++i];
2755: #ifdef NeXT
2756: /* Allow NeXT's -bsd switch. */
2757: else if (WORD_SWITCH (p))
2758: {
2759: n_switches++;
2760: i += WORD_SWITCH_TAKES_ARG (p);
2761: }
2762: #endif /* NeXT */
2763: else
2764: spec_machine = p + 1;
2765: break;
2766:
2767: #ifdef NEXT_SEMANTICS
2768: case 'N':
2769: if (WORD_SWITCH (p))
2770: {
2771: if (! strcmp (p, "-NEXTSTEP-deployment-target"))
2772: {
2773: int major, minor;
2774: if (i + 1 == argc)
2775: fatal ("argument to -NEXTSTEP-deployment-target missing");
2776: sscanf (argv[i+1], "%d.%d", &major, &minor);
2777: if (major != 3 || minor < 2 || minor > 3)
2778: fatal ("NEXTSTEP deployment target `%d.%d' out of bounds",
2779: major, minor);
2780:
2781: }
2782: n_switches++;
2783: i += WORD_SWITCH_TAKES_ARG (p);
2784: }
2785: break;
2786:
2787: case 'k':
2788: n_switches++;
2789: /* If they do anything other than exactly `-k', continue */
2790: /* on to give the error. */
2791: if (p[1] != 0)
2792: break;
2793: break;
2794: #endif
2795:
2796: case 'B':
2797: {
2798: int *temp = (int *) xmalloc (sizeof (int));
2799: char *value;
2800: if (p[1] == 0 && i + 1 == argc)
2801: fatal ("argument to `-B' is missing");
2802: if (p[1] == 0)
2803: value = argv[++i];
2804: else
2805: value = p + 1;
2806: add_prefix (&exec_prefix, value, 1, 0, temp);
2807: add_prefix (&startfile_prefix, value, 1, 0, temp);
2808: }
2809: break;
2810:
2811: case 'v': /* Print our subcommands and print versions. */
2812: n_switches++;
2813: /* If they do anything other than exactly `-v', don't set
2814: verbose_flag; rather, continue on to give the error. */
2815: if (p[1] != 0)
2816: break;
2817: verbose_flag++;
2818: break;
2819:
2820: case 'V':
2821: if (p[1] == 0 && i + 1 == argc)
2822: fatal ("argument to `-V' is missing");
2823: if (p[1] == 0)
2824: spec_version = argv[++i];
2825: else
2826: spec_version = p + 1;
2827: break;
2828:
2829: #ifdef NEXT_FAT_OUTPUT
2830: case 'a':
2831: if (!strcmp (p, "arch"))
2832: {
2833: NXArchInfo const* temp;
2834: int j, duplicate = 0;
2835:
2836: if (i + 1 == argc)
2837: fatal ("argument to `-arch' is missing");
2838:
2839: temp = NXGetArchInfoFromName (argv[++i]);
2840: if (temp == 0)
2841: fatal ("unknown architecture `%s'", argv[i]);
2842:
2843: for (j = 0; j < arch_count; j++)
2844: if (!strcmp (temp->name, arch_array[j]->name))
2845: duplicate = 1;
2846:
2847: if (!duplicate)
2848: {
2849: arch_count++;
2850: if (arch_array == NULL)
2851: arch_array = (NXArchInfo const **)
2852: xmalloc (arch_count * sizeof (NXArchInfo*));
2853: else
2854: arch_array = (NXArchInfo const **)
2855: xrealloc (arch_array,
2856: arch_count * sizeof (NXArchInfo*));
2857:
2858: arch_array[arch_count - 1] = temp;
2859: }
2860:
2861: n_switches++;
2862: break;
2863: }
2864: case 'd':
2865: if (!strcmp (p, "dependency-file"))
2866: {
2867: if (i + 1 == argc)
2868: fatal ("argument to `-dependency-file' is missing");
2869: dependency_output_file = argv[++i];
2870: break;
2871: }
2872: #endif /* NEXT_FAT_OUTPUT */
2873:
2874: case 's':
2875: if (!strcmp (p, "save-temps"))
2876: {
2877: save_temps_flag = 1;
2878: n_switches++;
2879: break;
2880: }
2881: default:
2882: n_switches++;
2883:
2884: if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
2885: i += SWITCH_TAKES_ARG (c) - (p[1] != 0);
2886: else if (WORD_SWITCH_TAKES_ARG (p))
2887: i += WORD_SWITCH_TAKES_ARG (p);
2888: }
2889: }
2890: else
2891: n_infiles++;
2892: }
2893:
2894: /* Set up the search paths before we go looking for config files. */
2895:
2896: /* These come before the md prefixes so that we will find gcc's subcommands
2897: (such as cpp) rather than those of the host system. */
2898: /* Use 2 as fourth arg meaning try just the machine as a suffix,
2899: as well as trying the machine and the version. */
2900: add_prefix (&exec_prefix, standard_exec_prefix, 0, 2, NULL_PTR);
2901: add_prefix (&exec_prefix, standard_exec_prefix_1, 0, 2, NULL_PTR);
2902: #ifdef NeXT
2903: add_prefix (&exec_prefix, standard_exec_prefix_2, 0, 2, NULL_PTR);
2904: #endif
2905:
2906: add_prefix (&startfile_prefix, standard_exec_prefix, 0, 1, NULL_PTR);
2907: add_prefix (&startfile_prefix, standard_exec_prefix_1, 0, 1, NULL_PTR);
2908: #ifdef NeXT
2909: add_prefix (&startfile_prefix, standard_exec_prefix_2, 0, 1, NULL_PTR);
2910: #endif
2911:
2912: tooldir_prefix = concat (tooldir_base_prefix, spec_machine, "/");
2913:
2914: /* If tooldir is relative, base it on exec_prefix. A relative
2915: tooldir lets us move the installed tree as a unit.
2916:
2917: If GCC_EXEC_PREFIX is defined, then we want to add two relative
2918: directories, so that we can search both the user specified directory
2919: and the standard place. */
2920:
2921: if (*tooldir_prefix != '/')
2922: {
2923: if (gcc_exec_prefix)
2924: {
2925: char *gcc_exec_tooldir_prefix
2926: = concat (concat (gcc_exec_prefix, spec_machine, "/"),
2927: concat (spec_version, "/", tooldir_prefix),
2928: "");
2929:
2930: add_prefix (&exec_prefix, concat (gcc_exec_tooldir_prefix, "bin", "/"),
2931: 0, 0, NULL_PTR);
2932: add_prefix (&startfile_prefix, concat (gcc_exec_tooldir_prefix, "lib", "/"),
2933: 0, 0, NULL_PTR);
2934: }
2935:
2936: tooldir_prefix = concat (concat (standard_exec_prefix, spec_machine, "/"),
2937: concat (spec_version, "/", tooldir_prefix),
2938: "");
2939: }
2940:
2941: add_prefix (&exec_prefix, concat (tooldir_prefix, "bin", "/"),
2942: 0, 0, NULL_PTR);
2943: add_prefix (&startfile_prefix, concat (tooldir_prefix, "lib", "/"),
2944: 0, 0, NULL_PTR);
2945:
2946: /* More prefixes are enabled in main, after we read the specs file
2947: and determine whether this is cross-compilation or not. */
2948:
2949:
2950: /* Then create the space for the vectors and scan again. */
2951:
2952: switches = ((struct switchstr *)
2953: xmalloc ((n_switches + 1) * sizeof (struct switchstr)));
2954: infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile));
2955: n_switches = 0;
2956: n_infiles = 0;
2957: last_language_n_infiles = -1;
2958:
2959: /* This, time, copy the text of each switch and store a pointer
2960: to the copy in the vector of switches.
2961: Store all the infiles in their vector. */
2962:
2963: for (i = 1; i < argc; i++)
2964: {
2965: /* Just skip the switches that were handled by the preceding loop. */
2966: if (!strcmp (argv[i], "-Xlinker"))
2967: i++;
2968: else if (! strncmp (argv[i], "-Wl,", 4))
2969: ;
2970: else if (! strncmp (argv[i], "-Wa,", 4))
2971: ;
2972: else if (! strcmp (argv[i], "-print-libgcc-file-name"))
2973: ;
2974: else if (argv[i][0] == '+' && argv[i][1] == 'e')
2975: {
2976: /* Compensate for the +e options to the C++ front-end;
2977: they're there simply for cfront call-compatibility. We do
2978: some magic in default_compilers to pass them down properly.
2979: Note we deliberately start at the `+' here, to avoid passing
2980: -e0 or -e1 down into the linker. */
2981: switches[n_switches].part1 = &argv[i][0];
2982: switches[n_switches].args = 0;
2983: switches[n_switches].valid = 0;
2984: n_switches++;
2985: }
2986: else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l')
2987: {
2988: register char *p = &argv[i][1];
2989: register int c = *p;
2990:
2991: #ifdef NeXT
2992: /* Allow NeXT's -bsd switch */
2993: if ((c == 'B' || c == 'b' || c == 'V')
2994: && ! WORD_SWITCH (p))
2995: #else
2996: if (c == 'B' || c == 'b' || c == 'V')
2997: #endif /* NeXT */
2998: {
2999: /* Skip a separate arg, if any. */
3000: if (p[1] == 0)
3001: i++;
3002: continue;
3003: }
3004: #ifdef NeXT
3005: if (c == 'd' && !strcmp (p, "dependency-file"))
3006: {
3007: i++;
3008: continue;
3009: }
3010:
3011: /* effectively translate -NEXTSTEP-deployment-target 3.3 into -k */
3012: if (c == 'N' && !strcmp (p, "NEXTSTEP-deployment-target"))
3013: {
3014: int major, minor;
3015: if (i + 1 == argc)
3016: fatal ("argument to -NEXTSTEP-deployment-target missing");
3017: sscanf (argv[i+1], "%d.%d", &major, &minor);
3018: if (major != 3 || minor < 2 || minor > 3)
3019: fatal ("NEXTSTEP deployment target `%d.%d' out of bounds",
3020: major, minor);
3021: if (minor == 3)
3022: {
3023: argv[++i] = "-k";
3024: p = &argv[i][1];
3025: c = *p;
3026: }
3027: else
3028: {
3029: i++;
3030: continue;
3031: }
3032: }
3033: #endif
3034: if (c == 'x')
3035: {
3036: if (p[1] == 0 && i + 1 == argc)
3037: fatal ("argument to `-x' is missing");
3038: if (p[1] == 0)
3039: spec_lang = argv[++i];
3040: else
3041: spec_lang = p + 1;
3042: if (! strcmp (spec_lang, "none"))
3043: /* Suppress the warning if -xnone comes after the last input file,
3044: because alternate command interfaces like g++ might find it
3045: useful to place -xnone after each input file. */
3046: spec_lang = default_language;
3047: else
3048: last_language_n_infiles = n_infiles;
3049: continue;
3050: }
3051:
3052: switches[n_switches].part1 = p;
3053: /* Deal with option arguments in separate argv elements. */
3054: if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
3055: || WORD_SWITCH_TAKES_ARG (p))
3056: {
3057: int j = 0;
3058: int n_args = WORD_SWITCH_TAKES_ARG (p);
3059:
3060: if (n_args == 0)
3061: {
3062: /* Count only the option arguments in separate argv elements. */
3063: n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
3064: }
3065: if (i + n_args >= argc)
3066: fatal ("argument to `-%s' is missing", p);
3067: switches[n_switches].args
3068: = (char **) xmalloc ((n_args + 1) * sizeof (char *));
3069: while (j < n_args)
3070: switches[n_switches].args[j++] = argv[++i];
3071: /* Null-terminate the vector. */
3072: switches[n_switches].args[j] = 0;
3073: }
3074: #ifdef WORD_SWITCH
3075: else if ((*switches_need_spaces != 0 && (c == 'o' || c == 'L'))
3076: && !WORD_SWITCH(p))
3077: #else
3078: else if (*switches_need_spaces != 0 && (c == 'o' || c == 'L'))
3079: #endif /* WORD_SWITCH */
3080: {
3081: /* On some systems, ld cannot handle -o or -L without space.
3082: So split the -o or -L from its argument. */
3083: switches[n_switches].part1 = (c == 'o' ? "o" : "L");
3084: switches[n_switches].args = (char **) xmalloc (2 * sizeof (char *));
3085: switches[n_switches].args[0] = xmalloc (strlen (p));
3086: strcpy (switches[n_switches].args[0], &p[1]);
3087: switches[n_switches].args[1] = 0;
3088: }
3089: #ifdef NEXT_SEMANTICS
3090: else if(c == 'O' && !strncmp (p, "ObjC", 4))
3091: {
3092: if (p[4] == 0)
3093: default_language = "c";
3094: else
3095: default_language = "c++";
3096: switches[n_switches].args = 0;
3097: }
3098: #endif /* NEXT_SEMANTICS */
3099: else
3100: switches[n_switches].args = 0;
3101: switches[n_switches].valid = 0;
3102: /* This is always valid, since gcc.c itself understands it. */
3103: if (!strcmp (p, "save-temps") || !strcmp (p, "arch"))
3104: switches[n_switches].valid = 1;
3105: n_switches++;
3106: }
3107: else
3108: {
3109: if ((argv[i][0] != '-' || argv[i][1] != 'l')
3110: && strcmp (argv[i], "-")
3111: && access (argv[i], R_OK) < 0)
3112: {
3113: perror_with_name (argv[i]);
3114: error_count++;
3115: }
3116: else
3117: {
3118: infiles[n_infiles].language = spec_lang;
3119: infiles[n_infiles++].name = argv[i];
3120: }
3121: }
3122: }
3123:
3124: if (n_infiles == last_language_n_infiles && spec_lang != 0)
3125: error ("Warning: `-x %s' after last input file has no effect", spec_lang);
3126:
3127: switches[n_switches].part1 = 0;
3128: infiles[n_infiles].name = 0;
3129:
3130: /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake. */
3131: if (gcc_exec_prefix)
3132: {
3133: temp = (char *) xmalloc (strlen (gcc_exec_prefix) + strlen (spec_version)
3134: + strlen (spec_machine) + 3);
3135: strcpy (temp, gcc_exec_prefix);
3136: strcat (temp, spec_machine);
3137: strcat (temp, "/");
3138: strcat (temp, spec_version);
3139: strcat (temp, "/");
3140: gcc_exec_prefix = temp;
3141: }
3142: }
3143:
3144: /* Process a spec string, accumulating and running commands. */
3145:
3146: /* These variables describe the input file name.
3147: input_file_number is the index on outfiles of this file,
3148: so that the output file name can be stored for later use by %o.
3149: input_basename is the start of the part of the input file
3150: sans all directory names, and basename_length is the number
3151: of characters starting there excluding the suffix .c or whatever. */
3152:
3153: static char *input_filename;
3154: static int input_file_number;
3155: static int input_filename_length;
3156: static int basename_length;
3157: static char *input_basename;
3158: static char *input_suffix;
3159:
3160: /* These are variables used within do_spec and do_spec_1. */
3161:
3162: /* Nonzero if an arg has been started and not yet terminated
3163: (with space, tab or newline). */
3164: static int arg_going;
3165:
3166: /* Nonzero means %d or %g has been seen; the next arg to be terminated
3167: is a temporary file name. */
3168: static int delete_this_arg;
3169:
3170: /* Nonzero means %w has been seen; the next arg to be terminated
3171: is the output file name of this compilation. */
3172: static int this_is_output_file;
3173:
3174: #ifdef NEXT_FAT_OUTPUT
3175: /* Nonzero means %m has been seen; the next arg to be terminated
3176: is the output file name of the compilation of this architecture. */
3177: static int this_is_arch_merge_file;
3178: #endif /* NEXT_FAT_OUTPUT */
3179:
3180: /* Nonzero means %s has been seen; the next arg to be terminated
3181: is the name of a library file and we should try the standard
3182: search dirs for it. */
3183: static int this_is_library_file;
3184:
3185: /* Nonzero means that the input of this command is coming from a pipe. */
3186: static int input_from_pipe;
3187:
3188: /* Process the spec SPEC and run the commands specified therein.
3189: Returns 0 if the spec is successfully processed; -1 if failed. */
3190:
3191: static int
3192: do_spec (spec)
3193: char *spec;
3194: {
3195: int value;
3196:
3197: clear_args ();
3198: arg_going = 0;
3199: delete_this_arg = 0;
3200: this_is_output_file = 0;
3201: #ifdef NEXT_FAT_OUTPUT
3202: this_is_arch_merge_file = 0;
3203: #endif /* NEXT_FAT_OUTPUT */
3204: this_is_library_file = 0;
3205: input_from_pipe = 0;
3206:
3207: value = do_spec_1 (spec, 0, NULL_PTR);
3208:
3209: /* Force out any unfinished command.
3210: If -pipe, this forces out the last command if it ended in `|'. */
3211: if (value == 0)
3212: {
3213: if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
3214: argbuf_index--;
3215:
3216: if (argbuf_index > 0)
3217: value = execute ();
3218: }
3219:
3220: return value;
3221: }
3222:
3223: /* Process the sub-spec SPEC as a portion of a larger spec.
3224: This is like processing a whole spec except that we do
3225: not initialize at the beginning and we do not supply a
3226: newline by default at the end.
3227: INSWITCH nonzero means don't process %-sequences in SPEC;
3228: in this case, % is treated as an ordinary character.
3229: This is used while substituting switches.
3230: INSWITCH nonzero also causes SPC not to terminate an argument.
3231:
3232: Value is zero unless a line was finished
3233: and the command on that line reported an error. */
3234:
3235: static int
3236: do_spec_1 (spec, inswitch, soft_matched_part)
3237: char *spec;
3238: int inswitch;
3239: char *soft_matched_part;
3240: {
3241: register char *p = spec;
3242: register int c;
3243: int i;
3244: char *string;
3245: int value;
3246:
3247: while (c = *p++)
3248: /* If substituting a switch, treat all chars like letters.
3249: Otherwise, NL, SPC, TAB and % are special. */
3250: switch (inswitch ? 'a' : c)
3251: {
3252: case '\n':
3253: /* End of line: finish any pending argument,
3254: then run the pending command if one has been started. */
3255: if (arg_going)
3256: {
3257: obstack_1grow (&obstack, 0);
3258: string = obstack_finish (&obstack);
3259: if (this_is_library_file)
3260: string = find_file (string);
3261: store_arg (string, delete_this_arg, this_is_output_file
3262: #ifdef NEXT_FAT_OUTPUT
3263: || this_is_arch_merge_file
3264: #endif
3265: );
3266: if (this_is_output_file)
3267: outfiles[input_file_number] = string;
3268: #ifdef NEXT_FAT_OUTPUT
3269: else if (this_is_arch_merge_file)
3270: arch_merge_files[current_arch] = string;
3271: #endif /* NEXT_FAT_OUTPUT */
3272: }
3273: arg_going = 0;
3274:
3275: if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
3276: {
3277: int i;
3278: for (i = 0; i < n_switches; i++)
3279: if (!strcmp (switches[i].part1, "pipe"))
3280: break;
3281:
3282: /* A `|' before the newline means use a pipe here,
3283: but only if -pipe was specified.
3284: Otherwise, execute now and don't pass the `|' as an arg. */
3285: if (i < n_switches)
3286: {
3287: input_from_pipe = 1;
3288: switches[i].valid = 1;
3289: break;
3290: }
3291: else
3292: argbuf_index--;
3293: }
3294:
3295: if (argbuf_index > 0)
3296: {
3297: value = execute ();
3298: if (value)
3299: return value;
3300: }
3301: /* Reinitialize for a new command, and for a new argument. */
3302: clear_args ();
3303: arg_going = 0;
3304: delete_this_arg = 0;
3305: this_is_output_file = 0;
3306: this_is_library_file = 0;
3307: #ifdef NEXT_FAT_OUTPUT
3308: this_is_arch_merge_file = 0;
3309: #endif /* NEXT_FAT_OUTPUT */
3310: input_from_pipe = 0;
3311: break;
3312:
3313: case '|':
3314: /* End any pending argument. */
3315: if (arg_going)
3316: {
3317: obstack_1grow (&obstack, 0);
3318: string = obstack_finish (&obstack);
3319: if (this_is_library_file)
3320: string = find_file (string);
3321: store_arg (string, delete_this_arg, this_is_output_file
3322: #ifdef NEXT_FAT_OUTPUT
3323: || this_is_arch_merge_file
3324: #endif
3325: );
3326: if (this_is_output_file)
3327: outfiles[input_file_number] = string;
3328: #ifdef NEXT_FAT_OUTPUT
3329: else if (this_is_arch_merge_file)
3330: arch_merge_files[current_arch] = string;
3331: #endif /* NEXT_FAT_OUTPUT */
3332: }
3333:
3334: /* Use pipe */
3335: obstack_1grow (&obstack, c);
3336: arg_going = 1;
3337: break;
3338:
3339: case '\t':
3340: case ' ':
3341: /* Space or tab ends an argument if one is pending. */
3342: if (arg_going)
3343: {
3344: obstack_1grow (&obstack, 0);
3345: string = obstack_finish (&obstack);
3346: if (this_is_library_file)
3347: string = find_file (string);
3348: store_arg (string, delete_this_arg, this_is_output_file
3349: #ifdef NEXT_FAT_OUTPUT
3350: || this_is_arch_merge_file
3351: #endif
3352: );
3353: if (this_is_output_file)
3354: outfiles[input_file_number] = string;
3355: #ifdef NEXT_FAT_OUTPUT
3356: else if (this_is_arch_merge_file)
3357: arch_merge_files[current_arch] = string;
3358: #endif /* NEXT_FAT_OUTPUT */
3359: }
3360: /* Reinitialize for a new argument. */
3361: arg_going = 0;
3362: delete_this_arg = 0;
3363: this_is_output_file = 0;
3364: #ifdef NEXT_FAT_OUTPUT
3365: this_is_arch_merge_file = 0;
3366: #endif /* NEXT_FAT_OUTPUT */
3367: this_is_library_file = 0;
3368: break;
3369:
3370: case '%':
3371: switch (c = *p++)
3372: {
3373: case 0:
3374: fatal ("Invalid specification! Bug in cc.");
3375:
3376: case 'b':
3377: obstack_grow (&obstack, input_basename, basename_length);
3378: arg_going = 1;
3379: break;
3380:
3381: case 'd':
3382: delete_this_arg = 2;
3383: break;
3384:
3385: /* Dump out the directories specified with LIBRARY_PATH,
3386: followed by the absolute directories
3387: that we search for startfiles. */
3388: case 'D':
3389: {
3390: struct prefix_list *pl = startfile_prefix.plist;
3391: int bufsize = 100;
3392: char *buffer = (char *) xmalloc (bufsize);
3393: int idx;
3394:
3395: for (; pl; pl = pl->next)
3396: {
3397: #ifdef RELATIVE_PREFIX_NOT_LINKDIR
3398: /* Used on systems which record the specified -L dirs
3399: and use them to search for dynamic linking. */
3400: /* Relative directories always come from -B,
3401: and it is better not to use them for searching
3402: at run time. In particular, stage1 loses */
3403: if (pl->prefix[0] != '/')
3404: continue;
3405: #endif
3406: if (machine_suffix)
3407: {
3408: if (is_directory (pl->prefix, machine_suffix, 1))
3409: {
3410: do_spec_1 ("-L", 0, NULL_PTR);
3411: #ifdef SPACE_AFTER_L_OPTION
3412: do_spec_1 (" ", 0, NULL_PTR);
3413: #endif
3414: do_spec_1 (pl->prefix, 1, NULL_PTR);
3415: /* Remove slash from machine_suffix. */
3416: if (strlen (machine_suffix) >= bufsize)
3417: bufsize = strlen (machine_suffix) * 2 + 1;
3418: buffer = (char *) xrealloc (buffer, bufsize);
3419: strcpy (buffer, machine_suffix);
3420: idx = strlen (buffer);
3421: if (buffer[idx - 1] == '/')
3422: buffer[idx - 1] = 0;
3423: do_spec_1 (buffer, 1, NULL_PTR);
3424: /* Make this a separate argument. */
3425: do_spec_1 (" ", 0, NULL_PTR);
3426: }
3427: }
3428: if (!pl->require_machine_suffix)
3429: {
3430: if (is_directory (pl->prefix, "", 1))
3431: {
3432: do_spec_1 ("-L", 0, NULL_PTR);
3433: #ifdef SPACE_AFTER_L_OPTION
3434: do_spec_1 (" ", 0, NULL_PTR);
3435: #endif
3436: /* Remove slash from pl->prefix. */
3437: if (strlen (pl->prefix) >= bufsize)
3438: bufsize = strlen (pl->prefix) * 2 + 1;
3439: buffer = (char *) xrealloc (buffer, bufsize);
3440: strcpy (buffer, pl->prefix);
3441: idx = strlen (buffer);
3442: if (buffer[idx - 1] == '/')
3443: buffer[idx - 1] = 0;
3444: do_spec_1 (buffer, 1, NULL_PTR);
3445: /* Make this a separate argument. */
3446: do_spec_1 (" ", 0, NULL_PTR);
3447: }
3448: }
3449: }
3450: free (buffer);
3451: }
3452: break;
3453:
3454: case 'e':
3455: /* {...:%efoo} means report an error with `foo' as error message
3456: and don't execute any more commands for this file. */
3457: {
3458: char *q = p;
3459: char *buf;
3460: while (*p != 0 && *p != '\n') p++;
3461: buf = (char *) alloca (p - q + 1);
3462: strncpy (buf, q, p - q);
3463: buf[p - q] = 0;
3464: error ("%s", buf);
3465: return -1;
3466: }
3467: break;
3468:
3469: #ifdef NEXT_SEMANTICS
3470: case 'B':
3471: /* {...:%Bfoo} means report the stage foo to ProjectBuilder */
3472: {
3473: char *q = p;
3474: char *buf;
3475: while (*p != 0 && *p != '\n') p++;
3476: buf = (char *) xmalloc (p - q + 1 + 30);
3477: strncpy (buf, q, p - q);
3478: buf[p - q] = 0;
3479: if (multi_arch)
3480: {
3481: const char *curr = arch_array[current_arch]->name;
3482:
3483: strcat (buf, " %%s for ");
3484:
3485: if (! strcmp (curr, "i386"))
3486: strcat (buf, "Intel");
3487: else if (! strcmp (curr, "hppa"))
3488: strcat (buf, "HPPA");
3489: else if (! strcmp (curr, "m68k"))
3490: strcat (buf, "NeXT");
3491: else
3492: strcat (buf, curr);
3493:
3494: }
3495: SAVE_REPORT_EVENT (-1, NULL, input_basename, \
3496: 0, buf, 0, 0, 0);
3497: }
3498: break;
3499: #endif
3500:
3501: case 'g':
3502: case 'u':
3503: case 'U':
3504: if (save_temps_flag)
3505: obstack_grow (&obstack, input_basename, basename_length);
3506: else
3507: {
3508: #ifdef MKTEMP_EACH_FILE
3509: /* ??? This has a problem: the total number of
3510: values mktemp can return is limited.
3511: That matters for the names of object files.
3512: In 2.4, do something about that. */
3513: struct temp_name *t;
3514: char *suffix = p;
3515: while (*p == '.' || isalpha (*p))
3516: p++;
3517:
3518: /* See if we already have an association of %g/%u/%U and
3519: suffix. */
3520: for (t = temp_names; t; t = t->next)
3521: if (t->length == p - suffix
3522: && strncmp (t->suffix, suffix, p - suffix) == 0
3523: && t->unique == (c != 'g'))
3524: break;
3525:
3526: /* Make a new association if needed. %u requires one. */
3527: if (t == 0 || c == 'u')
3528: {
3529: if (t == 0)
3530: {
3531: t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
3532: t->next = temp_names;
3533: temp_names = t;
3534: }
3535: t->length = p - suffix;
3536: t->suffix = save_string (suffix, p - suffix);
3537: t->unique = (c != 'g');
3538: choose_temp_base ();
3539: t->filename = temp_filename;
3540: t->filename_length = temp_filename_length;
3541: }
3542:
3543: obstack_grow (&obstack, t->filename, t->filename_length);
3544: delete_this_arg = 1;
3545: #else
3546: obstack_grow (&obstack, temp_filename, temp_filename_length);
3547: if (c == 'u' || c == 'U')
3548: {
3549: static int unique;
3550: char buff[9];
3551: if (c == 'u')
3552: unique++;
3553: sprintf (buff, "%d", unique);
3554: obstack_grow (&obstack, buff, strlen (buff));
3555: }
3556: #endif
3557: delete_this_arg = 1;
3558: }
3559: arg_going = 1;
3560: break;
3561:
3562: case 'i':
3563: obstack_grow (&obstack, input_filename, input_filename_length);
3564: arg_going = 1;
3565: break;
3566:
3567: case 'I':
3568: if (gcc_exec_prefix)
3569: {
3570: do_spec_1 ("-iprefix", 1, NULL_PTR);
3571: /* Make this a separate argument. */
3572: do_spec_1 (" ", 0, NULL_PTR);
3573: do_spec_1 (gcc_exec_prefix, 1, NULL_PTR);
3574: do_spec_1 (" ", 0, NULL_PTR);
3575: }
3576: break;
3577:
3578: case 'o':
3579: {
3580: register int f;
3581: for (f = 0; f < n_infiles; f++)
3582: store_arg (outfiles[f], 0, 0);
3583: }
3584: break;
3585:
3586: case 's':
3587: this_is_library_file = 1;
3588: break;
3589:
3590: case 'w':
3591: this_is_output_file = 1;
3592: break;
3593:
3594: #ifdef NEXT_FAT_OUTPUT
3595: case 'f':
3596: this_is_arch_merge_file = 1;
3597: break;
3598: #endif /* NEXT_FAT_OUTPUT */
3599:
3600: case 'W':
3601: {
3602: int index = argbuf_index;
3603: /* Handle the {...} following the %W. */
3604: if (*p != '{')
3605: abort ();
3606: p = handle_braces (p + 1);
3607: if (p == 0)
3608: return -1;
3609: /* If any args were output, mark the last one for deletion
3610: on failure. */
3611: if (argbuf_index != index)
3612: record_temp_file (argbuf[argbuf_index - 1], 0, 1);
3613: break;
3614: }
3615:
3616: /* %x{OPTION} records OPTION for %X to output. */
3617: case 'x':
3618: {
3619: char *p1 = p;
3620: char *string;
3621:
3622: /* Skip past the option value and make a copy. */
3623: if (*p != '{')
3624: abort ();
3625: while (*p++ != '}')
3626: ;
3627: string = save_string (p1 + 1, p - p1 - 2);
3628:
3629: /* See if we already recorded this option. */
3630: for (i = 0; i < n_linker_options; i++)
3631: if (! strcmp (string, linker_options[i]))
3632: {
3633: free (string);
3634: return 0;
3635: }
3636:
3637: /* This option is new; add it. */
3638: n_linker_options++;
3639: if (!linker_options)
3640: linker_options
3641: = (char **) xmalloc (n_linker_options * sizeof (char **));
3642: else
3643: linker_options
3644: = (char **) xrealloc (linker_options,
3645: n_linker_options * sizeof (char **));
3646:
3647: linker_options[n_linker_options - 1] = string;
3648: }
3649: break;
3650:
3651: /* Dump out the options accumulated previously using %x,
3652: -Xlinker and -Wl,. */
3653: case 'X':
3654: for (i = 0; i < n_linker_options; i++)
3655: {
3656: do_spec_1 (linker_options[i], 1, NULL_PTR);
3657: /* Make each accumulated option a separate argument. */
3658: do_spec_1 (" ", 0, NULL_PTR);
3659: }
3660: break;
3661:
3662: #ifdef NEXT_FAT_OUTPUT
3663: case 'T':
3664: obstack_grow (&obstack, arch_array[current_arch]->name,
3665: strlen (arch_array[current_arch]->name));
3666: arg_going = 1;
3667: break;
3668:
3669: case 'F':
3670: {
3671: register int i;
3672: for (i = 0; i < arch_count; i++) {
3673: store_arg ("-arch", 0, 0);
3674: store_arg (arch_array[i]->name, 0, 0);
3675: store_arg (arch_merge_files[i], 0, 0);
3676: }
3677: }
3678: break;
3679:
3680: case 'M':
3681: {
3682: if (dependency_output_file == NULL)
3683: {
3684: obstack_grow (&obstack, input_basename, basename_length);
3685: obstack_grow (&obstack, ".d", 2);
3686: }
3687: else
3688: obstack_grow (&obstack, dependency_output_file,
3689: strlen (dependency_output_file));
3690: arg_going = 1;
3691: }
3692: break;
3693: #endif /* NEXT_FAT_OUTPUT */
3694:
3695: /* Dump out the options accumulated previously using -Wa,. */
3696: case 'Y':
3697: for (i = 0; i < n_assembler_options; i++)
3698: {
3699: do_spec_1 (assembler_options[i], 1, NULL_PTR);
3700: /* Make each accumulated option a separate argument. */
3701: do_spec_1 (" ", 0, NULL_PTR);
3702: }
3703: break;
3704:
3705: /* Here are digits and numbers that just process
3706: a certain constant string as a spec. */
3707:
3708: case '1':
3709: value = do_spec_1 (cc1_spec, 0, NULL_PTR);
3710: if (value != 0)
3711: return value;
3712: break;
3713:
3714: case '2':
3715: value = do_spec_1 (cc1plus_spec, 0, NULL_PTR);
3716: if (value != 0)
3717: return value;
3718: break;
3719:
3720: case 'a':
3721: value = do_spec_1 (asm_spec, 0, NULL_PTR);
3722: if (value != 0)
3723: return value;
3724: break;
3725:
3726: case 'A':
3727: value = do_spec_1 (asm_final_spec, 0, NULL_PTR);
3728: if (value != 0)
3729: return value;
3730: break;
3731:
3732: case 'c':
3733: value = do_spec_1 (signed_char_spec, 0, NULL_PTR);
3734: if (value != 0)
3735: return value;
3736: break;
3737:
3738: case 'C':
3739: value = do_spec_1 (cpp_spec, 0, NULL_PTR);
3740: if (value != 0)
3741: return value;
3742: break;
3743:
3744: case 'E':
3745: value = do_spec_1 (endfile_spec, 0, NULL_PTR);
3746: if (value != 0)
3747: return value;
3748: break;
3749:
3750: case 'l':
3751: value = do_spec_1 (link_spec, 0, NULL_PTR);
3752: if (value != 0)
3753: return value;
3754: break;
3755:
3756: case 'L':
3757: value = do_spec_1 (lib_spec, 0, NULL_PTR);
3758: if (value != 0)
3759: return value;
3760: break;
3761:
3762: case 'p':
3763: {
3764: char *x = (char *) alloca (strlen (cpp_predefines) + 1);
3765: char *buf = x;
3766: char *y;
3767:
3768: /* Copy into BUF all of the -D options in CPP_PREDEFINES that
3769: do not begin with __. */
3770: y = cpp_predefines;
3771: while (*y != 0)
3772: {
3773: if (! strncmp (y, "-D", 2) && strncmp (y + 2, "__", 2))
3774: /* Copy the whole option. */
3775: while (*y && *y != ' ' && *y != '\t')
3776: *x++ = *y++;
3777: else if (*y == ' ' || *y == '\t')
3778: /* Copy whitespace to the result. */
3779: *x++ = *y++;
3780: /* Don't copy other options. */
3781: else
3782: y++;
3783: }
3784:
3785: *x = 0;
3786:
3787: value = do_spec_1 (buf, 0, NULL_PTR);
3788: if (value != 0)
3789: return value;
3790: }
3791: break;
3792:
3793: case 'P':
3794: {
3795: char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
3796: char *buf = x;
3797: char *y;
3798:
3799: /* Copy all of CPP_PREDEFINES into BUF,
3800: but put __ after every -D and at the end of each arg. */
3801: y = cpp_predefines;
3802: while (*y != 0)
3803: {
3804: if (! strncmp (y, "-D", 2))
3805: {
3806: int flag = 0;
3807:
3808: *x++ = *y++;
3809: *x++ = *y++;
3810:
3811: if (strncmp (y, "__", 2))
3812: {
3813: /* Stick __ at front of macro name. */
3814: *x++ = '_';
3815: *x++ = '_';
3816: /* Arrange to stick __ at the end as well. */
3817: flag = 1;
3818: }
3819:
3820: /* Copy the macro name. */
3821: while (*y && *y != '=' && *y != ' ' && *y != '\t')
3822: *x++ = *y++;
3823:
3824: if (flag)
3825: {
3826: *x++ = '_';
3827: *x++ = '_';
3828: }
3829:
3830: /* Copy the value given, if any. */
3831: while (*y && *y != ' ' && *y != '\t')
3832: *x++ = *y++;
3833: }
3834: else if (*y == ' ' || *y == '\t')
3835: /* Copy whitespace to the result. */
3836: *x++ = *y++;
3837: /* Don't copy -A options */
3838: else
3839: y++;
3840: }
3841: *x++ = ' ';
3842:
3843: /* Copy into BUF all of CPP_PREDEFINES that do not begin with
3844: __, but put __ after every -D. */
3845: y = cpp_predefines;
3846: while (*y != 0)
3847: {
3848: if (! strncmp (y, "-D", 2) && strncmp (y + 2, "__", 2))
3849: {
3850: *x++ = *y++;
3851: *x++ = *y++;
3852:
3853: /* Stick __ at front of macro name. */
3854: *x++ = '_';
3855: *x++ = '_';
3856:
3857: /* Copy the macro name. */
3858: while (*y && *y != '=' && *y != ' ' && *y != '\t')
3859: *x++ = *y++;
3860:
3861: /* Copy the value given, if any. */
3862: while (*y && *y != ' ' && *y != '\t')
3863: *x++ = *y++;
3864: }
3865: else if (*y == ' ' || *y == '\t')
3866: /* Copy whitespace to the result. */
3867: *x++ = *y++;
3868: /* Don't copy -A options */
3869: else
3870: y++;
3871: }
3872: *x++ = ' ';
3873:
3874: /* Copy all of the -A options in CPP_PREDEFINES into BUF. */
3875: y = cpp_predefines;
3876: while (*y != 0)
3877: {
3878: if (! strncmp (y, "-A", 2))
3879: /* Copy the whole option. */
3880: while (*y && *y != ' ' && *y != '\t')
3881: *x++ = *y++;
3882: else if (*y == ' ' || *y == '\t')
3883: /* Copy whitespace to the result. */
3884: *x++ = *y++;
3885: /* Don't copy other options. */
3886: else
3887: y++;
3888: }
3889:
3890: *x = 0;
3891:
3892: value = do_spec_1 (buf, 0, NULL_PTR);
3893: if (value != 0)
3894: return value;
3895: }
3896: break;
3897:
3898: case 'S':
3899: value = do_spec_1 (startfile_spec, 0, NULL_PTR);
3900: if (value != 0)
3901: return value;
3902: break;
3903:
3904: /* Here we define characters other than letters and digits. */
3905:
3906: case '{':
3907: p = handle_braces (p);
3908: if (p == 0)
3909: return -1;
3910: break;
3911:
3912: case ':':
3913: fatal ("Internal compiler error: dangling else in spec");
3914: break;
3915:
3916: case '%':
3917: obstack_1grow (&obstack, '%');
3918: break;
3919:
3920: case '*':
3921: do_spec_1 (soft_matched_part, 1, NULL_PTR);
3922: do_spec_1 (" ", 0, NULL_PTR);
3923: break;
3924:
3925: /* Process a string found as the value of a spec given by name.
3926: This feature allows individual machine descriptions
3927: to add and use their own specs.
3928: %[...] modifies -D options the way %P does;
3929: %(...) uses the spec unmodified. */
3930: case '(':
3931: case '[':
3932: {
3933: char *name = p;
3934: struct spec_list *sl;
3935: int len;
3936:
3937: /* The string after the S/P is the name of a spec that is to be
3938: processed. */
3939: while (*p && *p != ')' && *p != ']')
3940: p++;
3941:
3942: /* See if it's in the list */
3943: for (len = p - name, sl = specs; sl; sl = sl->next)
3944: if (strncmp (sl->name, name, len) == 0 && !sl->name[len])
3945: {
3946: name = sl->spec;
3947: break;
3948: }
3949:
3950: if (sl)
3951: {
3952: if (c == '(')
3953: {
3954: value = do_spec_1 (name, 0, NULL_PTR);
3955: if (value != 0)
3956: return value;
3957: }
3958: else
3959: {
3960: char *x = (char *) alloca (strlen (name) * 2 + 1);
3961: char *buf = x;
3962: char *y = name;
3963:
3964: /* Copy all of NAME into BUF, but put __ after
3965: every -D and at the end of each arg, */
3966: while (1)
3967: {
3968: if (! strncmp (y, "-D", 2))
3969: {
3970: *x++ = '-';
3971: *x++ = 'D';
3972: *x++ = '_';
3973: *x++ = '_';
3974: y += 2;
3975: }
3976: else if (*y == ' ' || *y == 0)
3977: {
3978: *x++ = '_';
3979: *x++ = '_';
3980: if (*y == 0)
3981: break;
3982: else
3983: *x++ = *y++;
3984: }
3985: else
3986: *x++ = *y++;
3987: }
3988: *x = 0;
3989:
3990: value = do_spec_1 (buf, 0, NULL_PTR);
3991: if (value != 0)
3992: return value;
3993: }
3994: }
3995:
3996: /* Discard the closing paren or bracket. */
3997: if (*p)
3998: p++;
3999: }
4000: break;
4001:
4002: case 'v':
4003: {
4004: int c1 = *p++; /* Select first or second version number. */
4005: char *p = spec_version;
4006: char *q, *copy;
4007: /* If desired, advance to second version number. */
4008: if (c1 == '2')
4009: {
4010: /* Set P after the first period. */
4011: while (*p != '.') p++;
4012: p++;
4013: }
4014: /* Set Q at the next period or at the end. */
4015: q = p;
4016: while (*q != '.' && *q != 0) q++;
4017: /* Put that part into the command. */
4018: obstack_grow (&obstack, p, q - p);
4019: arg_going = 1;
4020: }
4021: break;
4022:
4023: case '|':
4024: if (input_from_pipe)
4025: do_spec_1 ("-", 0, NULL_PTR);
4026: break;
4027:
4028: default:
4029: abort ();
4030: }
4031: break;
4032:
4033: case '\\':
4034: /* Backslash: treat next character as ordinary. */
4035: c = *p++;
4036:
4037: /* fall through */
4038: default:
4039: /* Ordinary character: put it into the current argument. */
4040: obstack_1grow (&obstack, c);
4041: arg_going = 1;
4042: }
4043:
4044: return 0; /* End of string */
4045: }
4046:
4047: /* Skip an else construct %:{...} after a
4048: conditional which was true. */
4049:
4050: static char*
4051: skip_maybe_else (p)
4052: char *p;
4053: {
4054: if (p[0] == '%' && p[1] == ':' && p[2] == '{')
4055: {
4056: int c = 1;
4057: p += 3;
4058: while (c)
4059: {
4060: if (*p == '{')
4061: c += 1;
4062: else if (*p == '}')
4063: c -= 1;
4064: else if (*p == 0)
4065: fatal ("Internal compiler error: premature end of spec");
4066: p++;
4067: }
4068: }
4069: return p;
4070: }
4071:
4072: /* Perform an else construct %:{...} after a
4073: conditional which was false */
4074:
4075: static char*
4076: perform_maybe_else (p)
4077: char *p;
4078: {
4079: char *q = skip_maybe_else (p);
4080: if (q != p)
4081: {
4082: if (do_spec_1 (save_string (p+3, q-p-4), 0, NULL_PTR) < 0)
4083: return 0;
4084: }
4085: return q;
4086: }
4087:
4088: /* Return 0 if we call do_spec_1 and that returns -1. */
4089:
4090: static char *
4091: handle_braces (p)
4092: register char *p;
4093: {
4094: register char *q;
4095: int n_filters = 0;
4096: int filter_cnt;
4097: char *filters[20];
4098: int negate[20];
4099: int suffix[20];
4100: int pipe = 0;
4101: int conditional_succeeded = 0;
4102:
4103: if (*p == '|')
4104: /* A `|' after the open-brace means,
4105: if the test fails, output a single minus sign rather than nothing.
4106: This is used in %{|!pipe:...}. */
4107: pipe = 1, ++p;
4108:
4109: while (1)
4110: {
4111: if (*p == '!')
4112: /* A `!' after the open-brace negates the condition:
4113: succeed if the specified switch is not present. */
4114: negate[n_filters] = 1, ++p;
4115: else
4116: negate[n_filters] = 0;
4117:
4118: if (*p == '.')
4119: /* A `.' after the open-brace means test against the current suffix. */
4120: {
4121: if (pipe)
4122: fatal ("Internal compiler error: combining pipe and suffix in spec");
4123:
4124: suffix[n_filters] = 1;
4125: ++p;
4126: }
4127: else
4128: suffix[n_filters] = 0;
4129:
4130: /* remember beginning of this filter element */
4131: filters[n_filters++] = p;
4132:
4133: while (*p != ':' && *p != '}' && *p != '|') p++;
4134:
4135: if (*p == '|')
4136: {
4137: p++;
4138: continue;
4139: }
4140: else
4141: break;
4142: }
4143:
4144: /* this is one char past the last filter element, so
4145: we can use the following macro. */
4146: filters[n_filters] = p+1;
4147:
4148: /* There is some replacement text */
4149: if (*p != '}')
4150: {
4151: register int count = 1;
4152: q = p + 1;
4153: while (count > 0)
4154: {
4155: if (*q == '{')
4156: count++;
4157: else if (*q == '}')
4158: count--;
4159: else if (*q == 0)
4160: fatal ("Internal compiler error: premature end of spec");
4161: q++;
4162: }
4163: }
4164: else
4165: q = p + 1;
4166:
4167: for (filter_cnt = 0; filter_cnt < n_filters; filter_cnt++)
4168: {
4169: char *filter_start = filters[filter_cnt];
4170: char *filter_end = filters[filter_cnt+1] - 1;
4171: int filter_strlen;
4172: int empty_body = (p[0] == '}');
4173: char *body_start = p+1;
4174: int body_strlen = q - p - 2;
4175:
4176: /* skip backwards till we see a seperator */
4177: while (*filter_end != ':' && *filter_end != '|' && *filter_end != '}')
4178: filter_end--;
4179:
4180: filter_strlen = filter_end - filter_start;
4181:
4182: #ifdef NEXT_FAT_OUTPUT
4183: if (filter_start[0] == '@')
4184: {
4185: if (empty_body)
4186: fatal ("Internal compiler error: empty body in `@' conditioned spec");
4187: if (filter_strlen != 1)
4188: fatal ("Internal compiler error: `@' condition illegal in spec");
4189:
4190: if (negate[filter_cnt] != multi_arch)
4191: {
4192: if (do_spec_1 (save_string (body_start, body_strlen), 0, NULL) < 0)
4193: return 0;
4194: else
4195: return skip_maybe_else (q);
4196: }
4197: else
4198: continue;
4199: }
4200: #endif /* NEXT_FAT_OUTPUT */
4201:
4202: if (suffix[filter_cnt])
4203: {
4204: int found = (input_suffix != 0
4205: && strlen (input_suffix) == filter_strlen
4206: && strncmp (input_suffix, filter_start, filter_strlen) == 0);
4207:
4208: if (empty_body)
4209: fatal ("Internal compiler error: empty body in suffic conditioned spec");
4210:
4211: if (negate[filter_cnt] != found)
4212: {
4213: if (do_spec_1 (save_string (body_start, body_strlen), 0, NULL_PTR) < 0)
4214: return 0;
4215: else
4216: return skip_maybe_else (q);
4217: }
4218: else
4219: continue;
4220: }
4221:
4222: else if (filter_end[-1] == '*' && empty_body)
4223: {
4224: /* Substitute all matching switches as separate args. */
4225: register int i;
4226: for (i = 0; i < n_switches; i++)
4227: if (!strncmp (switches[i].part1, filter_start, filter_strlen-1))
4228: give_switch (i, 0);
4229: continue;
4230: }
4231: else
4232: {
4233: /* Test for presence of the specified switch. */
4234: register int i;
4235: int present = 0;
4236:
4237: /* If name specified ends in *, as in {x*:...},
4238: check for %* and handle that case. */
4239: if (filter_end[-1] == '*' && !negate[filter_cnt])
4240: {
4241: int substitution;
4242: char *r = p;
4243:
4244: /* First see whether we have %*. */
4245: substitution = 0;
4246: while (r < q)
4247: {
4248: if (*r == '%' && r[1] == '*')
4249: substitution = 1;
4250: r++;
4251: }
4252: /* If we do, handle that case. */
4253: if (substitution)
4254: {
4255: /* Substitute all matching switches as separate args.
4256: But do this by substituting for %*
4257: in the text that follows the colon. */
4258:
4259: char *string = save_string (body_start, body_strlen);
4260:
4261: for (i = 0; i < n_switches; i++)
4262: if (!strncmp (switches[i].part1, filter_start, filter_strlen))
4263: {
4264: do_spec_1 (string, 0, &switches[i].part1[filter_strlen]);
4265: /* Pass any arguments this switch has. */
4266: give_switch (i, 1);
4267: }
4268:
4269: continue;
4270: }
4271: }
4272:
4273: /* If name specified ends in *, as in {x*:...},
4274: check for presence of any switch name starting with x. */
4275: if (filter_end[-1] == '*')
4276: {
4277: for (i = 0; i < n_switches; i++)
4278: {
4279: if (!strncmp (switches[i].part1, filter_start, filter_strlen-1))
4280: {
4281: switches[i].valid = 1;
4282: present = 1;
4283: }
4284: }
4285: }
4286: /* Otherwise, check for presence of exact name specified. */
4287: else
4288: {
4289: for (i = 0; i < n_switches; i++)
4290: {
4291: if (!strncmp (switches[i].part1, filter_start, filter_strlen)
4292: && switches[i].part1[filter_strlen] == 0)
4293: {
4294: switches[i].valid = 1;
4295: present = 1;
4296: break;
4297: }
4298: }
4299: }
4300:
4301: /* If it is as desired (present for %{s...}, absent for %{-s...})
4302: then substitute either the switch or the specified
4303: conditional text. */
4304: if (present != negate[filter_cnt])
4305: {
4306: conditional_succeeded = 1;
4307:
4308: if (empty_body)
4309: {
4310: give_switch (i, 0);
4311: }
4312: else
4313: {
4314: if (do_spec_1 (save_string (body_start, body_strlen), 0, NULL_PTR) < 0)
4315: return 0;
4316: else
4317: return skip_maybe_else (q);
4318: }
4319: }
4320: }
4321: }
4322:
4323:
4324: if (pipe && !conditional_succeeded)
4325: {
4326: /* Here if a %{|...} conditional fails: output a minus sign,
4327: which means "standard output" or "standard input". */
4328: do_spec_1 ("-", 0, NULL_PTR);
4329: return skip_maybe_else (q);
4330: }
4331:
4332: return perform_maybe_else (q);
4333: }
4334:
4335: /* Pass a switch to the current accumulating command
4336: in the same form that we received it.
4337: SWITCHNUM identifies the switch; it is an index into
4338: the vector of switches gcc received, which is `switches'.
4339: This cannot fail since it never finishes a command line.
4340:
4341: If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */
4342:
4343: static void
4344: give_switch (switchnum, omit_first_word)
4345: int switchnum;
4346: int omit_first_word;
4347: {
4348: if (!omit_first_word)
4349: {
4350: do_spec_1 ("-", 0, NULL_PTR);
4351: do_spec_1 (switches[switchnum].part1, 1, NULL_PTR);
4352: }
4353: do_spec_1 (" ", 0, NULL_PTR);
4354: if (switches[switchnum].args != 0)
4355: {
4356: char **p;
4357: for (p = switches[switchnum].args; *p; p++)
4358: {
4359: do_spec_1 (*p, 1, NULL_PTR);
4360: do_spec_1 (" ", 0, NULL_PTR);
4361: }
4362: }
4363: switches[switchnum].valid = 1;
4364: }
4365:
4366: /* Search for a file named NAME trying various prefixes including the
4367: user's -B prefix and some standard ones.
4368: Return the absolute file name found. If nothing is found, return NAME. */
4369:
4370: static char *
4371: find_file (name)
4372: char *name;
4373: {
4374: char *newname;
4375:
4376: newname = find_a_file (&startfile_prefix, name, R_OK);
4377: return newname ? newname : name;
4378: }
4379:
4380: /* Determine whether a directory exists. If LINKER, return 0 for
4381: certain fixed names not needed by the linker. If not LINKER, it is
4382: only important to return 0 if the host machine has a small ARG_MAX
4383: limit. */
4384:
4385: static int
4386: is_directory (path1, path2, linker)
4387: char *path1;
4388: char *path2;
4389: int linker;
4390: {
4391: int len1 = strlen (path1);
4392: int len2 = strlen (path2);
4393: char *path = (char *) alloca (3 + len1 + len2);
4394: char *cp;
4395: struct stat st;
4396:
4397: #ifndef SMALL_ARG_MAX
4398: if (! linker)
4399: return 1;
4400: #endif
4401:
4402: /* Construct the path from the two parts. Ensure the string ends with "/.".
4403: The resulting path will be a directory even if the given path is a
4404: symbolic link. */
4405: bcopy (path1, path, len1);
4406: bcopy (path2, path + len1, len2);
4407: cp = path + len1 + len2;
4408: if (cp[-1] != '/')
4409: *cp++ = '/';
4410: *cp++ = '.';
4411: *cp = '\0';
4412:
4413: /* Exclude directories that the linker is known to search. */
4414: if (linker
4415: && ((cp - path == 6 && strcmp (path, "/lib/.") == 0)
4416: || (cp - path == 10 && strcmp (path, "/usr/lib/.") == 0)))
4417: return 0;
4418:
4419: return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
4420: }
4421:
4422: /* On fatal signals, delete all the temporary files. */
4423:
4424: static void
4425: fatal_error (signum)
4426: int signum;
4427: {
4428: signal (signum, SIG_DFL);
4429: delete_failure_queue ();
4430: delete_temp_files ();
4431: /* Get the same signal again, this time not handled,
4432: so its normal effect occurs. */
4433: kill (getpid (), signum);
4434: }
4435:
4436: int
4437: main (argc, argv)
4438: int argc;
4439: char **argv;
4440: {
4441: register int i;
4442: int j;
4443: int value;
4444: int linker_was_run = 0;
4445: char *explicit_link_files;
4446: char *specs_file;
4447: #ifdef REPORT_EVENT
4448: char *link_output = "a.out";
4449: #endif
4450: char *p;
4451:
4452: p = argv[0] + strlen (argv[0]);
4453: while (p != argv[0] && p[-1] != '/') --p;
4454: programname = p;
4455:
4456: if (signal (SIGINT, SIG_IGN) != SIG_IGN)
4457: signal (SIGINT, fatal_error);
4458: #ifdef SIGHUP
4459: if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
4460: signal (SIGHUP, fatal_error);
4461: #endif
4462: if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
4463: signal (SIGTERM, fatal_error);
4464: #ifdef SIGPIPE
4465: if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
4466: signal (SIGPIPE, fatal_error);
4467: #endif
4468:
4469: argbuf_length = 10;
4470: argbuf = (char **) xmalloc (argbuf_length * sizeof (char *));
4471:
4472: obstack_init (&obstack);
4473:
4474: /* Set up to remember the pathname of gcc and any options
4475: needed for collect. We use argv[0] instead of programname because
4476: we need the complete pathname. */
4477: obstack_init (&collect_obstack);
4478: obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=")-1);
4479: obstack_grow (&collect_obstack, argv[0], strlen (argv[0])+1);
4480: putenv (obstack_finish (&collect_obstack));
4481:
4482: /* Choose directory for temp files. */
4483:
4484: choose_temp_base ();
4485:
4486: /* Make a table of what switches there are (switches, n_switches).
4487: Make a table of specified input files (infiles, n_infiles).
4488: Decode switches that are handled locally. */
4489:
4490: process_command (argc, argv);
4491:
4492: /* Initialize the vector of specs to just the default.
4493: This means one element containing 0s, as a terminator. */
4494:
4495: compilers = (struct compiler *) xmalloc (sizeof default_compilers);
4496: bcopy (default_compilers, compilers, sizeof default_compilers);
4497: n_compilers = n_default_compilers;
4498:
4499: /* Read specs from a file if there is one. */
4500:
4501: #ifdef NEXT_FAT_OUTPUT
4502: /* Determine the default architecture, if none was specified.
4503: Compute the architecture family name. */
4504: if (arch_array == NULL)
4505: {
4506: #ifndef DEFAULT_TARGET_ARCH
4507: const NXArchInfo *family_arch;
4508: #endif
4509: arch_family = (char **) xmalloc (sizeof (char *));
4510: arch_array = (NXArchInfo const **) xmalloc (sizeof (NXArchInfo*));
4511: arch_count = 1;
4512:
4513: #ifdef DEFAULT_TARGET_ARCH
4514:
4515: arch_family[0] = DEFAULT_TARGET_ARCH;
4516: arch_array[0] = NXGetArchInfoFromName (arch_family[0]);
4517:
4518: if (arch_array[0] == 0)
4519: fatal ("unknown default architecture");
4520:
4521: #else /* not DEFAULT_TARGET_ARCH */
4522: arch_family = (char **) xmalloc (sizeof (char *));
4523: arch_count = 1;
4524: arch_array = (NXArchInfo const **) xmalloc (sizeof (NXArchInfo*));
4525:
4526: if ((arch_array[0] = NXGetLocalArchInfo ()) == 0)
4527: fatal ("unknown default architecture");
4528:
4529: family_arch = NXGetArchInfoFromCpuType (arch_array[0]->cputype,
4530: CPU_SUBTYPE_MULTIPLE);
4531: arch_family[0] = (char*) (family_arch == NULL
4532: ? arch_array[0]->name
4533: : family_arch->name);
4534: #endif /* not DEFAULT_TARGET_ARCH */
4535: }
4536: else
4537: {
4538: arch_family = (char **) xmalloc (sizeof (char *) * arch_count);
4539: for (i = 0; i < arch_count; i++)
4540: {
4541: const NXArchInfo *family_arch;
4542: family_arch = NXGetArchInfoFromCpuType (arch_array[i]->cputype,
4543: CPU_SUBTYPE_MULTIPLE);
4544: arch_family[i] = (char *) (family_arch == NULL
4545: ? arch_array[i]->name
4546: : family_arch->name);
4547: }
4548: }
4549:
4550: multi_arch = (arch_count > 1);
4551:
4552: arch_merge_files = (char **) xmalloc (arch_count * sizeof (char *));
4553:
4554: machine_suffix = concat (arch_family[0], "/", "");
4555: just_machine_suffix = concat (arch_family[0], "/", "");
4556: #else /* not NEXT_FAT_OUTPUT */
4557: machine_suffix = concat (spec_machine, "/", concat (spec_version, "/", ""));
4558: just_machine_suffix = concat (spec_machine, "/", "");
4559: #endif /* not NEXT_FAT_OUTPUT */
4560:
4561: specs_file = find_a_file (&startfile_prefix, "specs", R_OK);
4562: /* Read the specs file unless it is a default one. */
4563: if (specs_file != 0 && strcmp (specs_file, "specs"))
4564: read_specs (specs_file);
4565:
4566: /* If not cross-compiling, look for startfiles in the standard places. */
4567: /* The fact that these are done here, after reading the specs file,
4568: means that it cannot be found in these directories.
4569: But that's okay. It should never be there anyway. */
4570: if (!cross_compile)
4571: {
4572: #ifdef MD_EXEC_PREFIX
4573: add_prefix (&exec_prefix, md_exec_prefix, 0, 0, NULL_PTR);
4574: add_prefix (&startfile_prefix, md_exec_prefix, 0, 0, NULL_PTR);
4575: #endif
4576:
4577: #ifdef MD_STARTFILE_PREFIX
4578: add_prefix (&startfile_prefix, md_startfile_prefix, 0, 0, NULL_PTR);
4579: #endif
4580:
4581: #ifdef MD_STARTFILE_PREFIX_1
4582: add_prefix (&startfile_prefix, md_startfile_prefix_1, 0, 0, NULL_PTR);
4583: #endif
4584:
4585: /* If standard_startfile_prefix is relative, base it on
4586: standard_exec_prefix. This lets us move the installed tree
4587: as a unit. If GCC_EXEC_PREFIX is defined, base
4588: standard_startfile_prefix on that as well. */
4589: if (*standard_startfile_prefix == '/')
4590: add_prefix (&startfile_prefix, standard_startfile_prefix, 0, 0,
4591: NULL_PTR);
4592: else
4593: {
4594: if (gcc_exec_prefix)
4595: add_prefix (&startfile_prefix,
4596: concat (gcc_exec_prefix,
4597: standard_startfile_prefix,
4598: ""),
4599: 0, 0, NULL_PTR);
4600: add_prefix (&startfile_prefix,
4601: concat (standard_exec_prefix,
4602: machine_suffix,
4603: standard_startfile_prefix),
4604: 0, 0, NULL_PTR);
4605: }
4606:
4607: add_prefix (&startfile_prefix, standard_startfile_prefix_1, 0, 0,
4608: NULL_PTR);
4609: add_prefix (&startfile_prefix, standard_startfile_prefix_2, 0, 0,
4610: NULL_PTR);
4611: #if 0 /* Can cause surprises, and one can use -B./ instead. */
4612: add_prefix (&startfile_prefix, "./", 0, 1, NULL_PTR);
4613: #endif
4614: }
4615:
4616: /* Now we have the specs.
4617: Set the `valid' bits for switches that match anything in any spec. */
4618:
4619: validate_all_switches ();
4620:
4621: /* Warn about any switches that no pass was interested in. */
4622:
4623: for (i = 0; i < n_switches; i++)
4624: if (! switches[i].valid)
4625: error ("unrecognized option `-%s'", switches[i].part1);
4626:
4627: if (print_libgcc_file_name)
4628: {
4629: printf ("%s\n", find_file ("libgcc.a"));
4630: exit (0);
4631: }
4632:
4633: if (dump_specs)
4634: {
4635: printf ("*asm:\n%s\n\n", asm_spec);
4636: printf ("*asm_final:\n%s\n\n", asm_final_spec);
4637: printf ("*cpp:\n%s\n\n", cpp_spec);
4638: printf ("*cc1:\n%s\n\n", cc1_spec);
4639: printf ("*cc1plus:\n%s\n\n", cc1plus_spec);
4640: printf ("*endfile:\n%s\n\n", endfile_spec);
4641: printf ("*link:\n%s\n\n", link_spec);
4642: printf ("*lib:\n%s\n\n", lib_spec);
4643: printf ("*startfile:\n%s\n\n", startfile_spec);
4644: printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces);
4645: printf ("*signed_char:\n%s\n\n", signed_char_spec);
4646: printf ("*predefines:\n%s\n\n", cpp_predefines);
4647: printf ("*cross_compile:\n%d\n\n", cross_compile);
4648:
4649: exit (0);
4650: }
4651:
4652: /* Obey some of the options. */
4653:
4654: if (verbose_flag)
4655: {
4656: #ifdef NeXT
4657: extern char *next_version;
4658: fprintf (stderr, "NeXT Computer, Inc. version %s, ",
4659: next_version);
4660: #endif
4661: fprintf (stderr, "gcc version %s\n", version_string);
4662: if (n_infiles == 0)
4663: exit (0);
4664: }
4665:
4666: if (n_infiles == 0)
4667: fatal ("No input files");
4668:
4669: /* Make a place to record the compiler output file names
4670: that correspond to the input files. */
4671:
4672: outfiles = (char **) xmalloc (n_infiles * sizeof (char *));
4673: bzero (outfiles, n_infiles * sizeof (char *));
4674:
4675: /* Record which files were specified explicitly as link input. */
4676:
4677: explicit_link_files = xmalloc (n_infiles);
4678: bzero (explicit_link_files, n_infiles);
4679:
4680: for (i = 0; i < n_infiles; i++)
4681: {
4682: register struct compiler *cp = 0;
4683: int this_file_error = 0;
4684:
4685: /* Tell do_spec what to substitute for %i. */
4686:
4687: input_filename = infiles[i].name;
4688: input_filename_length = strlen (input_filename);
4689: input_file_number = i;
4690:
4691: /* Use the same thing in %o, unless cp->spec says otherwise. */
4692:
4693: outfiles[i] = input_filename;
4694:
4695: /* Figure out which compiler from the file's suffix. */
4696:
4697: cp = lookup_compiler (infiles[i].name, input_filename_length,
4698: infiles[i].language);
4699:
4700: #ifdef NeXT
4701: if (! cp)
4702: {
4703: int i;
4704: for (i = 0; i < n_switches; i++)
4705: {
4706: if (!strcmp (switches[i].part1, "E"))
4707: {
4708: cp = lookup_compiler (0, 0, "c");
4709: /* now turn on the -traditional-cpp, somehow */
4710: for ( i = 0; i < n_switches; i++ ) {
4711: if (!strcmp (switches[i].part1, "traditional-cpp")
4712: || !strcmp (switches[i].part1, "traditional")
4713: || !strcmp (switches[i].part1, "cpp"))
4714: break;
4715: }
4716: if (i == n_switches)
4717: {
4718: /* we didn't find the -traditional-cpp switch */
4719: switches
4720: = ((struct switchstr*)
4721: xrealloc (switches,
4722: sizeof (struct switchstr) * ++n_switches));
4723: switches[n_switches-1].part1 = "traditional-cpp";
4724: switches[n_switches-1].args = 0;
4725: switches[n_switches-1].valid = 1;
4726: }
4727: }
4728: }
4729: }
4730: #endif /* NeXT */
4731:
4732: if (cp)
4733: {
4734: /* Ok, we found an applicable compiler. Run its spec. */
4735: /* First say how much of input_filename to substitute for %b */
4736: register char *p;
4737: int len;
4738:
4739: input_basename = input_filename;
4740: for (p = input_filename; *p; p++)
4741: if (*p == '/')
4742: input_basename = p + 1;
4743:
4744: /* Find a suffix starting with the last period,
4745: and set basename_length to exclude that suffix. */
4746: basename_length = strlen (input_basename);
4747: p = input_basename + basename_length;
4748: while (p != input_basename && *p != '.') --p;
4749: if (*p == '.' && p != input_basename)
4750: {
4751: basename_length = p - input_basename;
4752: input_suffix = p + 1;
4753: }
4754: else
4755: input_suffix = "";
4756:
4757: len = 0;
4758: for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
4759: if (cp->spec[j])
4760: len += strlen (cp->spec[j]);
4761:
4762: p = (char *) xmalloc (len + 1);
4763:
4764: len = 0;
4765: for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
4766: if (cp->spec[j])
4767: {
4768: strcpy (p + len, cp->spec[j]);
4769: len += strlen (cp->spec[j]);
4770: }
4771: }
4772:
4773: if (cp)
4774: {
4775: /* Ok, we found an applicable compiler. Run its spec. */
4776: /* First say how much of input_filename to substitute for %b */
4777: register char *p;
4778: int len;
4779:
4780: input_basename = input_filename;
4781: for (p = input_filename; *p; p++)
4782: if (*p == '/')
4783: input_basename = p + 1;
4784:
4785: /* Find a suffix starting with the last period,
4786: and set basename_length to exclude that suffix. */
4787: basename_length = strlen (input_basename);
4788: p = input_basename + basename_length;
4789: while (p != input_basename && *p != '.') --p;
4790: if (*p == '.' && p != input_basename)
4791: {
4792: basename_length = p - input_basename;
4793: input_suffix = p + 1;
4794: }
4795: else
4796: input_suffix = "";
4797:
4798: len = 0;
4799: for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
4800: if (cp->spec[j])
4801: len += strlen (cp->spec[j]);
4802:
4803: p = (char *) xmalloc (len + 1);
4804:
4805: len = 0;
4806: for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++)
4807: if (cp->spec[j])
4808: {
4809: strcpy (p + len, cp->spec[j]);
4810: len += strlen (cp->spec[j]);
4811: }
4812:
4813: #ifndef NEXT_FAT_OUTPUT
4814: value = do_spec (p);
4815: free (p);
4816: if (value < 0)
4817: this_file_error = 1;
4818: #if 0
4819: #ifdef REPORT_EVENT
4820: SAVE_REPORT_EVENT (-1, NULL, input_basename, 0, "Compiling", 0, 0, 0);
4821: #endif
4822: #endif
4823: #else /* NEXT_FAT_OUTPUT */
4824: bzero (arch_merge_files, arch_count * sizeof (char *));
4825:
4826: for (current_arch = 0; current_arch < arch_count; current_arch++)
4827: {
4828: #if 0
4829: #ifdef REPORT_EVENT
4830: SAVE_REPORT_EVENT (-1, NULL, input_basename, 0,
4831: (multi_arch ? "Compiling for %s:" : "Compiling"),
4832: arch_array[current_arch]->name, 0, 0);
4833: #endif
4834: #endif
4835: if (multi_arch)
4836: {
4837: /* Read CPP predefines from architecture spec. */
4838:
4839: machine_suffix = concat (arch_family[current_arch], "/", "");
4840: just_machine_suffix =
4841: concat (arch_family[current_arch], "/", "");
4842:
4843: specs_file = find_a_file (&startfile_prefix, "specs", R_OK);
4844: /* Read the specs file unless it is a default one. */
4845: if (specs_file != 0 && strcmp (specs_file, "specs"))
4846: read_specs (specs_file);
4847: else
4848: fatal ("cannot read specs file.");
4849: }
4850:
4851: value = do_spec (p);
4852: if (value < 0)
4853: {
4854: this_file_error = 1;
4855: break;
4856: }
4857: }
4858:
4859: free (p);
4860:
4861: /* Run the merger after compiling all architectures. */
4862: if (multi_arch && !this_file_error)
4863: {
4864: #ifdef REPORT_EVENT
4865: SAVE_REPORT_EVENT (-1, NULL, input_basename, 0,
4866: "Combining", 0, 0, 0);
4867: #endif
4868: value = do_spec (ofile_merge_spec);
4869: if (value < 0)
4870: this_file_error = 1;
4871: value = do_spec (precomp_merge_spec);
4872: if (value < 0)
4873: this_file_error = 1;
4874: }
4875: #endif /* NEXT_FAT_OUTPUT */
4876: }
4877:
4878: /* If this file's name does not contain a recognized suffix,
4879: record it as explicit linker input. */
4880:
4881: else
4882: explicit_link_files[i] = 1;
4883:
4884: /* Clear the delete-on-failure queue, deleting the files in it
4885: if this compilation failed. */
4886:
4887: if (this_file_error)
4888: {
4889: delete_failure_queue ();
4890: error_count++;
4891: }
4892: /* If this compilation succeeded, don't delete those files later. */
4893: clear_failure_queue ();
4894: }
4895:
4896: /* Run ld to link all the compiler output files. */
4897:
4898: if (error_count == 0)
4899: {
4900: int tmp = execution_count;
4901: int i;
4902: int first_time;
4903:
4904: /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
4905: for collect. */
4906: putenv_from_prefixes (&exec_prefix, "COMPILER_PATH=");
4907: putenv_from_prefixes (&startfile_prefix, "LIBRARY_PATH=");
4908:
4909: /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
4910: the compiler. */
4911: obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
4912: sizeof ("COLLECT_GCC_OPTIONS=")-1);
4913:
4914: first_time = TRUE;
4915: for (i = 0; i < n_switches; i++)
4916: {
4917: char **args;
4918: if (!first_time)
4919: obstack_grow (&collect_obstack, " ", 1);
4920:
4921: first_time = FALSE;
4922: obstack_grow (&collect_obstack, "-", 1);
4923: obstack_grow (&collect_obstack, switches[i].part1,
4924: strlen (switches[i].part1));
4925:
4926: #ifdef REPORT_EVENT
4927: if (! strcmp (switches[i].part1, "o"))
4928: link_output = *switches[i].args;
4929: #endif
4930:
4931: for (args = switches[i].args; args && *args; args++)
4932: {
4933: obstack_grow (&collect_obstack, " ", 1);
4934: obstack_grow (&collect_obstack, *args, strlen (*args));
4935: }
4936: }
4937: obstack_grow (&collect_obstack, "\0", 1);
4938: putenv (obstack_finish (&collect_obstack));
4939:
4940: #ifndef NEXT_FAT_OUTPUT
4941: value = do_spec (link_command_spec);
4942: if (value < 0)
4943: error_count = 1;
4944: #ifdef REPORT_EVENT
4945: SAVE_REPORT_EVENT (-1, NULL, NULL, 0, "Linking %s", link_output, 0, 0);
4946: #endif
4947: #else /* NEXT_FAT_OUTPUT */
4948: bzero (arch_merge_files, arch_count * sizeof (char *));
4949:
4950: for (current_arch = 0; current_arch < arch_count; current_arch++)
4951: {
4952: #ifdef REPORT_EVENT
4953: SAVE_REPORT_EVENT (-1, NULL, NULL, 0,
4954: (multi_arch ? "Linking %s for %s" : "Linking %s"),
4955: link_output, arch_array[current_arch]->name, 0);
4956: #endif
4957: value = do_spec (link_command_spec);
4958: if (value < 0)
4959: {
4960: error_count = 1;
4961: break;
4962: }
4963: }
4964: #endif /* NEXT_FAT_OUTPUT */
4965: linker_was_run = (tmp != execution_count);
4966: }
4967:
4968: #ifdef NEXT_FAT_OUTPUT
4969: /* Run the merger after linking all architectures. */
4970: if (multi_arch && error_count == 0)
4971: {
4972: #ifdef REPORT_EVENT
4973: SAVE_REPORT_EVENT (-1, NULL, NULL, 0,
4974: "Combining into %s", link_output, 0, 0);
4975: #endif
4976: value = do_spec (exec_merge_spec);
4977: if (value < 0)
4978: error_count = 1;
4979: }
4980: #endif /* NEXT_FAT_OUTPUT */
4981:
4982: /* Warn if a -B option was specified but the prefix was never used. */
4983: unused_prefix_warnings (&exec_prefix);
4984: unused_prefix_warnings (&startfile_prefix);
4985:
4986: /* If options said don't run linker,
4987: complain about input files to be given to the linker. */
4988:
4989: if (! linker_was_run && error_count == 0)
4990: for (i = 0; i < n_infiles; i++)
4991: if (explicit_link_files[i])
4992: error ("%s: linker input file unused since linking not done",
4993: outfiles[i]);
4994:
4995: /* Delete some or all of the temporary files we made. */
4996:
4997: if (error_count)
4998: delete_failure_queue ();
4999: delete_temp_files ();
5000:
5001: exit (error_count > 0 ? (signal_count ? 2 : 1) : 0);
5002: /* NOTREACHED */
5003: return 0;
5004: }
5005:
5006: /* Find the proper compilation spec for the file name NAME,
5007: whose length is LENGTH. LANGUAGE is the specified language,
5008: or 0 if none specified. */
5009:
5010: static struct compiler *
5011: lookup_compiler (name, length, language)
5012: char *name;
5013: int length;
5014: char *language;
5015: {
5016: struct compiler *cp;
5017:
5018: /* Look for the language, if one is spec'd. */
5019: if (language != 0)
5020: {
5021: for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
5022: {
5023: if (language != 0)
5024: {
5025: if (cp->suffix[0] == '@'
5026: && !strcmp (cp->suffix + 1, language))
5027: return cp;
5028: else if (cp->suffix[0] == '='
5029: && cp->spec[0][0] == '@'
5030: && !strcmp (cp->suffix + 1, language))
5031: {
5032: language = cp->spec[0] + 1;
5033: cp = compilers + n_compilers - 1;
5034: }
5035: }
5036: }
5037: error ("language %s not recognized", language);
5038: }
5039:
5040: /* Look for a suffix. */
5041: for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
5042: {
5043: if (/* The suffix `-' matches only the file name `-'. */
5044: (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
5045: ||
5046: (strlen (cp->suffix) < length
5047: /* See if the suffix matches the end of NAME. */
5048: && !strcmp (cp->suffix,
5049: name + length - strlen (cp->suffix))))
5050: {
5051: /* If we found any compiler at all for a suffix, return
5052: the default compiler, if one was specified. */
5053: if (default_language)
5054: return lookup_compiler (0, 0, default_language);
5055: if (cp->spec[0][0] == '@')
5056: {
5057: struct compiler *new;
5058: /* An alias entry maps a suffix to a language.
5059: Search for the language; pass 0 for NAME and LENGTH
5060: to avoid infinite recursion if language not found.
5061: Construct the new compiler spec. */
5062: language = cp->spec[0] + 1;
5063: new = (struct compiler *) xmalloc (sizeof (struct compiler));
5064: new->suffix = cp->suffix;
5065: bcopy (lookup_compiler (NULL_PTR, 0, language)->spec,
5066: new->spec, sizeof new->spec);
5067: return new;
5068: }
5069: /* A non-alias entry: return it. */
5070: return cp;
5071: }
5072: }
5073:
5074: return 0;
5075: }
5076:
5077: char *
5078: xmalloc (size)
5079: unsigned size;
5080: {
5081: register char *value = (char *) malloc (size);
5082: if (value == 0)
5083: fatal ("virtual memory exhausted");
5084: return value;
5085: }
5086:
5087: char *
5088: xrealloc (ptr, size)
5089: char *ptr;
5090: unsigned size;
5091: {
5092: register char *value = (char *) realloc (ptr, size);
5093: if (value == 0)
5094: fatal ("virtual memory exhausted");
5095: return value;
5096: }
5097:
5098: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
5099:
5100: static char *
5101: concat (s1, s2, s3)
5102: char *s1, *s2, *s3;
5103: {
5104: int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
5105: char *result = xmalloc (len1 + len2 + len3 + 1);
5106:
5107: strcpy (result, s1);
5108: strcpy (result + len1, s2);
5109: strcpy (result + len1 + len2, s3);
5110: *(result + len1 + len2 + len3) = 0;
5111:
5112: return result;
5113: }
5114:
5115: static char *
5116: save_string (s, len)
5117: char *s;
5118: int len;
5119: {
5120: register char *result = xmalloc (len + 1);
5121:
5122: bcopy (s, result, len);
5123: result[len] = 0;
5124: return result;
5125: }
5126:
5127: static void
5128: pfatal_with_name (name)
5129: char *name;
5130: {
5131: char *s;
5132:
5133: if (errno < sys_nerr)
5134: s = concat ("%s: ", sys_errlist[errno], "");
5135: else
5136: s = "cannot open %s";
5137: fatal (s, name);
5138: }
5139:
5140: static void
5141: perror_with_name (name)
5142: char *name;
5143: {
5144: char *s;
5145:
5146: if (errno < sys_nerr)
5147: s = concat ("%s: ", sys_errlist[errno], "");
5148: else
5149: s = "cannot open %s";
5150: error (s, name);
5151: }
5152:
5153: static void
5154: perror_exec (name)
5155: char *name;
5156: {
5157: char *s;
5158:
5159: if (errno < sys_nerr)
5160: s = concat ("installation problem, cannot exec %s: ",
5161: sys_errlist[errno], "");
5162: else
5163: s = "installation problem, cannot exec %s";
5164: error (s, name);
5165: }
5166:
5167: /* More 'friendly' abort that prints the line and file.
5168: config.h can #define abort fancy_abort if you like that sort of thing. */
5169:
5170: void
5171: fancy_abort ()
5172: {
5173: fatal ("Internal gcc abort.");
5174: }
5175:
5176: #ifdef HAVE_VPRINTF
5177:
5178: /* Output an error message and exit */
5179:
5180: static void
5181: fatal (va_alist)
5182: va_dcl
5183: {
5184: va_list ap;
5185: char *format;
5186:
5187: va_start (ap);
5188: format = va_arg (ap, char *);
5189: fprintf (stderr, "%s: ", programname);
5190: vfprintf (stderr, format, ap);
5191: va_end (ap);
5192: fprintf (stderr, "\n");
5193: delete_temp_files ();
5194: exit (1);
5195: }
5196:
5197: static void
5198: error (va_alist)
5199: va_dcl
5200: {
5201: va_list ap;
5202: char *format;
5203:
5204: va_start (ap);
5205: format = va_arg (ap, char *);
5206: fprintf (stderr, "%s: ", programname);
5207: vfprintf (stderr, format, ap);
5208: va_end (ap);
5209:
5210: fprintf (stderr, "\n");
5211: }
5212:
5213: #else /* not HAVE_VPRINTF */
5214:
5215: static void
5216: fatal (msg, arg1, arg2)
5217: char *msg, *arg1, *arg2;
5218: {
5219: error (msg, arg1, arg2);
5220: delete_temp_files ();
5221: exit (1);
5222: }
5223:
5224: static void
5225: error (msg, arg1, arg2)
5226: char *msg, *arg1, *arg2;
5227: {
5228: fprintf (stderr, "%s: ", programname);
5229: fprintf (stderr, msg, arg1, arg2);
5230: fprintf (stderr, "\n");
5231: }
5232:
5233: #endif /* not HAVE_VPRINTF */
5234:
5235:
5236: static void
5237: validate_all_switches ()
5238: {
5239: struct compiler *comp;
5240: register char *p;
5241: register char c;
5242: struct spec_list *spec;
5243:
5244: for (comp = compilers; comp->spec[0]; comp++)
5245: {
5246: int i;
5247: for (i = 0; i < sizeof comp->spec / sizeof comp->spec[0] && comp->spec[i]; i++)
5248: {
5249: p = comp->spec[i];
5250: while (c = *p++)
5251: if (c == '%' && *p == '{')
5252: /* We have a switch spec. */
5253: validate_switches (p + 1);
5254: }
5255: }
5256:
5257: /* look through the linked list of extra specs read from the specs file */
5258: for (spec = specs; spec ; spec = spec->next)
5259: {
5260: p = spec->spec;
5261: while (c = *p++)
5262: if (c == '%' && *p == '{')
5263: /* We have a switch spec. */
5264: validate_switches (p + 1);
5265: }
5266:
5267: p = link_command_spec;
5268: while (c = *p++)
5269: if (c == '%' && *p == '{')
5270: /* We have a switch spec. */
5271: validate_switches (p + 1);
5272:
5273: /* Now notice switches mentioned in the machine-specific specs. */
5274:
5275: p = asm_spec;
5276: while (c = *p++)
5277: if (c == '%' && *p == '{')
5278: /* We have a switch spec. */
5279: validate_switches (p + 1);
5280:
5281: p = asm_final_spec;
5282: while (c = *p++)
5283: if (c == '%' && *p == '{')
5284: /* We have a switch spec. */
5285: validate_switches (p + 1);
5286:
5287: p = cpp_spec;
5288: while (c = *p++)
5289: if (c == '%' && *p == '{')
5290: /* We have a switch spec. */
5291: validate_switches (p + 1);
5292:
5293: p = signed_char_spec;
5294: while (c = *p++)
5295: if (c == '%' && *p == '{')
5296: /* We have a switch spec. */
5297: validate_switches (p + 1);
5298:
5299: p = cc1_spec;
5300: while (c = *p++)
5301: if (c == '%' && *p == '{')
5302: /* We have a switch spec. */
5303: validate_switches (p + 1);
5304:
5305: p = cc1plus_spec;
5306: while (c = *p++)
5307: if (c == '%' && *p == '{')
5308: /* We have a switch spec. */
5309: validate_switches (p + 1);
5310:
5311: p = link_spec;
5312: while (c = *p++)
5313: if (c == '%' && *p == '{')
5314: /* We have a switch spec. */
5315: validate_switches (p + 1);
5316:
5317: p = lib_spec;
5318: while (c = *p++)
5319: if (c == '%' && *p == '{')
5320: /* We have a switch spec. */
5321: validate_switches (p + 1);
5322:
5323: p = startfile_spec;
5324: while (c = *p++)
5325: if (c == '%' && *p == '{')
5326: /* We have a switch spec. */
5327: validate_switches (p + 1);
5328: }
5329:
5330: /* Look at the switch-name that comes after START
5331: and mark as valid all supplied switches that match it. */
5332:
5333: static void
5334: validate_switches (start)
5335: char *start;
5336: {
5337: register char *p = start;
5338: char *filter;
5339: register int i;
5340: int suffix = 0;
5341:
5342: if (*p == '|')
5343: ++p;
5344:
5345: if (*p == '!')
5346: ++p;
5347:
5348: if (*p == '.')
5349: suffix = 1, ++p;
5350:
5351: filter = p;
5352: while (*p != ':' && *p != '}' && *p != '|') p++;
5353:
5354: if (suffix)
5355: ;
5356: else if (p[-1] == '*')
5357: {
5358: /* Mark all matching switches as valid. */
5359: --p;
5360: for (i = 0; i < n_switches; i++)
5361: if (!strncmp (switches[i].part1, filter, p - filter))
5362: switches[i].valid = 1;
5363: ++p;
5364: }
5365: else
5366: {
5367: /* Mark an exact matching switch as valid. */
5368: for (i = 0; i < n_switches; i++)
5369: {
5370: if (!strncmp (switches[i].part1, filter, p - filter)
5371: && switches[i].part1[p - filter] == 0)
5372: switches[i].valid = 1;
5373: }
5374: }
5375:
5376: if (*p == '|')
5377: validate_switches (p+1);
5378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.