Annotation of gcc/gcc.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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