Annotation of gcc/gcc.c, revision 1.1.1.9

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

unix.superglobalmegacorp.com

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