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