|
|
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.