Annotation of gcc/gcc.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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