Annotation of gcc/gcc.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.