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