00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include "config.h"
00078 #include "system.h"
00079 #include <signal.h>
00080 #if ! defined( SIGCHLD ) && defined( SIGCLD )
00081 # define SIGCHLD SIGCLD
00082 #endif
00083 #include "obstack.h"
00084 #include "intl.h"
00085 #include "prefix.h"
00086 #include "gcc.h"
00087 #include "flags.h"
00088
00089 #ifdef HAVE_SYS_RESOURCE_H
00090 #include <sys/resource.h>
00091 #endif
00092 #if defined (HAVE_DECL_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
00093 extern int getrusage PARAMS ((int, struct rusage *));
00094 #endif
00095
00096
00097
00098 #if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
00099 #define HAVE_TARGET_EXECUTABLE_SUFFIX
00100 #endif
00101
00102
00103 #ifdef HOST_EXECUTABLE_SUFFIX
00104 #define HAVE_HOST_EXECUTABLE_SUFFIX
00105 #else
00106 #define HOST_EXECUTABLE_SUFFIX ""
00107 #endif
00108
00109
00110 #ifdef TARGET_OBJECT_SUFFIX
00111 #define HAVE_TARGET_OBJECT_SUFFIX
00112 #else
00113 #define TARGET_OBJECT_SUFFIX ".o"
00114 #endif
00115
00116 #ifndef VMS
00117
00118
00119 #ifndef DIR_UP
00120 #define DIR_UP ".."
00121 #endif
00122 #endif
00123
00124 static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
00125
00126
00127 #ifndef LIBRARY_PATH_ENV
00128 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
00129 #endif
00130
00131 #ifndef HAVE_KILL
00132 #define kill(p,s) raise(s)
00133 #endif
00134
00135
00136
00137
00138 #define MIN_FATAL_STATUS 1
00139
00140
00141 int is_cpp_driver;
00142
00143
00144
00145 static int pass_exit_codes;
00146
00147
00148 #include "configargs.h"
00149
00150
00151
00152
00153 static int print_search_dirs;
00154
00155
00156
00157
00158 static const char *print_file_name = NULL;
00159
00160
00161
00162 static const char *print_prog_name = NULL;
00163
00164
00165
00166
00167 static int print_multi_directory;
00168
00169
00170
00171
00172 static int print_multi_os_directory;
00173
00174
00175
00176
00177 static int print_multi_lib;
00178
00179
00180
00181
00182 static int print_help_list;
00183
00184
00185
00186 static int verbose_flag;
00187
00188
00189
00190
00191
00192
00193 static int verbose_only_flag;
00194
00195
00196
00197 static int target_help_flag;
00198
00199
00200
00201
00202 static int report_times;
00203
00204
00205
00206
00207 static int save_temps_flag;
00208
00209
00210
00211 static const char *compiler_version;
00212
00213
00214
00215 static const char *const spec_version = DEFAULT_TARGET_VERSION;
00216
00217
00218
00219 static const char *spec_machine = DEFAULT_TARGET_MACHINE;
00220
00221
00222
00223
00224 #ifdef CROSS_COMPILE
00225 static const char *cross_compile = "1";
00226 #else
00227 static const char *cross_compile = "0";
00228 #endif
00229
00230 #ifdef MODIFY_TARGET_NAME
00231
00232
00233
00234
00235
00236 static const struct modify_target
00237 {
00238 const char *const sw;
00239 const enum add_del {ADD, DELETE} add_del;
00240 const char *const str;
00241 }
00242 modify_target[] = MODIFY_TARGET_NAME;
00243 #endif
00244
00245
00246
00247 static int error_count = 0;
00248
00249
00250
00251 static int greatest_status = 1;
00252
00253
00254
00255 static struct obstack obstack;
00256
00257
00258
00259
00260
00261
00262 static struct obstack collect_obstack;
00263
00264
00265
00266 #ifdef HAVE_GETRUSAGE
00267 static struct rusage rus, prus;
00268 #endif
00269
00270
00271 struct path_prefix;
00272
00273 static void init_spec PARAMS ((void));
00274 static void store_arg PARAMS ((const char *, int, int));
00275 static char *load_specs PARAMS ((const char *));
00276 static void read_specs PARAMS ((const char *, int));
00277 static void set_spec PARAMS ((const char *, const char *));
00278 static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const char *));
00279 static char *build_search_list PARAMS ((struct path_prefix *, const char *, int));
00280 static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *));
00281 static int access_check PARAMS ((const char *, int));
00282 static char *find_a_file PARAMS ((struct path_prefix *, const char *,
00283 int, int));
00284 static void add_prefix PARAMS ((struct path_prefix *, const char *,
00285 const char *, int, int, int *, int));
00286 static void translate_options PARAMS ((int *, const char *const **));
00287 static char *skip_whitespace PARAMS ((char *));
00288 static void delete_if_ordinary PARAMS ((const char *));
00289 static void delete_temp_files PARAMS ((void));
00290 static void delete_failure_queue PARAMS ((void));
00291 static void clear_failure_queue PARAMS ((void));
00292 static int check_live_switch PARAMS ((int, int));
00293 static const char *handle_braces PARAMS ((const char *));
00294 static const struct spec_function *lookup_spec_function PARAMS ((const char *));
00295 static const char *eval_spec_function PARAMS ((const char *, const char *));
00296 static const char *handle_spec_function PARAMS ((const char *));
00297 static char *save_string PARAMS ((const char *, int));
00298 static void set_collect_gcc_options PARAMS ((void));
00299 static int do_spec_1 PARAMS ((const char *, int, const char *));
00300 static int do_spec_2 PARAMS ((const char *));
00301 static void do_self_spec PARAMS ((const char *));
00302 static const char *find_file PARAMS ((const char *));
00303 static int is_directory PARAMS ((const char *, const char *, int));
00304 static void validate_switches PARAMS ((const char *));
00305 static void validate_all_switches PARAMS ((void));
00306 static void give_switch PARAMS ((int, int, int));
00307 static int used_arg PARAMS ((const char *, int));
00308 static int default_arg PARAMS ((const char *, int));
00309 static void set_multilib_dir PARAMS ((void));
00310 static void print_multilib_info PARAMS ((void));
00311 static void perror_with_name PARAMS ((const char *));
00312 static void pfatal_pexecute PARAMS ((const char *, const char *))
00313 ATTRIBUTE_NORETURN;
00314 static void notice PARAMS ((const char *, ...))
00315 ATTRIBUTE_PRINTF_1;
00316 static void display_help PARAMS ((void));
00317 static void add_preprocessor_option PARAMS ((const char *, int));
00318 static void add_assembler_option PARAMS ((const char *, int));
00319 static void add_linker_option PARAMS ((const char *, int));
00320 static void process_command PARAMS ((int, const char *const *));
00321 static int execute PARAMS ((void));
00322 static void alloc_args PARAMS ((void));
00323 static void clear_args PARAMS ((void));
00324 static void fatal_error PARAMS ((int));
00325 #ifdef ENABLE_SHARED_LIBGCC
00326 static void init_gcc_specs PARAMS ((struct obstack *,
00327 const char *, const char *,
00328 const char *));
00329 #endif
00330 #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
00331 static const char *convert_filename PARAMS ((const char *, int, int));
00332 #endif
00333
00334 static const char *if_exists_spec_function PARAMS ((int, const char **));
00335 static const char *if_exists_else_spec_function PARAMS ((int, const char **));
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 #ifndef ASM_SPEC
00528 #define ASM_SPEC ""
00529 #endif
00530
00531
00532
00533 #ifndef ASM_FINAL_SPEC
00534 #define ASM_FINAL_SPEC ""
00535 #endif
00536
00537
00538
00539 #ifndef CPP_SPEC
00540 #define CPP_SPEC ""
00541 #endif
00542
00543
00544
00545 #ifndef CC1_SPEC
00546 #define CC1_SPEC ""
00547 #endif
00548
00549
00550
00551 #ifndef CC1PLUS_SPEC
00552 #define CC1PLUS_SPEC ""
00553 #endif
00554
00555
00556
00557 #ifndef LINK_SPEC
00558 #define LINK_SPEC ""
00559 #endif
00560
00561
00562 #ifndef LIB_SPEC
00563 #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
00564 #endif
00565
00566
00567
00568 #ifndef LIBGCC_SPEC
00569 #if defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
00570
00571 #define LIBGCC_SPEC "libgcc.a%s"
00572 #else
00573 #define LIBGCC_SPEC "-lgcc"
00574 #endif
00575 #endif
00576
00577
00578 #ifndef STARTFILE_SPEC
00579 #define STARTFILE_SPEC \
00580 "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
00581 #endif
00582
00583
00584
00585 #ifndef SWITCHES_NEED_SPACES
00586 #define SWITCHES_NEED_SPACES ""
00587 #endif
00588
00589
00590 #ifndef ENDFILE_SPEC
00591 #define ENDFILE_SPEC ""
00592 #endif
00593
00594 #ifndef LINKER_NAME
00595 #define LINKER_NAME "collect2"
00596 #endif
00597
00598
00599
00600 #ifndef ASM_DEBUG_SPEC
00601 # if defined(DBX_DEBUGGING_INFO) && defined(DWARF2_DEBUGGING_INFO) \
00602 && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
00603 # define ASM_DEBUG_SPEC \
00604 (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG \
00605 ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}" \
00606 : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}")
00607 # else
00608 # if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
00609 # define ASM_DEBUG_SPEC "%{g*:--gstabs}"
00610 # endif
00611 # if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
00612 # define ASM_DEBUG_SPEC "%{g*:--gdwarf2}"
00613 # endif
00614 # endif
00615 #endif
00616 #ifndef ASM_DEBUG_SPEC
00617 # define ASM_DEBUG_SPEC ""
00618 #endif
00619
00620
00621
00622
00623
00624
00625 #ifndef LINK_GCC_C_SEQUENCE_SPEC
00626 #define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
00627 #endif
00628
00629 #ifndef LINK_PIE_SPEC
00630 #ifdef HAVE_LD_PIE
00631 #define LINK_PIE_SPEC "%{pie:-pie} "
00632 #else
00633 #define LINK_PIE_SPEC "%{pie:} "
00634 #endif
00635 #endif
00636
00637
00638
00639
00640
00641
00642
00643 #ifndef LINK_COMMAND_SPEC
00644 #define LINK_COMMAND_SPEC "\
00645 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
00646 %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
00647 %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
00648 %{static:} %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
00649 %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
00650 #endif
00651
00652 #ifndef LINK_LIBGCC_SPEC
00653 # ifdef LINK_LIBGCC_SPECIAL
00654
00655 # define LINK_LIBGCC_SPEC ""
00656 # else
00657
00658 # define LINK_LIBGCC_SPEC "%D"
00659 # endif
00660 #endif
00661
00662 #ifndef STARTFILE_PREFIX_SPEC
00663 # define STARTFILE_PREFIX_SPEC ""
00664 #endif
00665
00666 static const char *asm_debug;
00667 static const char *cpp_spec = CPP_SPEC;
00668 static const char *cpp_predefines = CPP_PREDEFINES;
00669 static const char *cc1_spec = CC1_SPEC;
00670 static const char *cc1plus_spec = CC1PLUS_SPEC;
00671 static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
00672 static const char *asm_spec = ASM_SPEC;
00673 static const char *asm_final_spec = ASM_FINAL_SPEC;
00674 static const char *link_spec = LINK_SPEC;
00675 static const char *lib_spec = LIB_SPEC;
00676 static const char *libgcc_spec = LIBGCC_SPEC;
00677 static const char *endfile_spec = ENDFILE_SPEC;
00678 static const char *startfile_spec = STARTFILE_SPEC;
00679 static const char *switches_need_spaces = SWITCHES_NEED_SPACES;
00680 static const char *linker_name_spec = LINKER_NAME;
00681 static const char *link_command_spec = LINK_COMMAND_SPEC;
00682 static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
00683 static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 static const char *trad_capable_cpp =
00695 "cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}";
00696
00697
00698
00699
00700 static const char *cpp_unique_options =
00701 "%{C:%{!E:%eGNU C does not support -C without using -E}}\
00702 %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
00703 %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
00704 %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
00705 %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
00706 %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
00707 %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
00708 %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
00709 %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
00710 %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
00711 %{E|M|MM:%W{o*}}";
00712
00713
00714
00715
00716
00717
00718 static const char *cpp_options =
00719 "%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
00720 %{O*} %{undef}";
00721
00722
00723
00724 static const char *cpp_debug_options = "%{d*}";
00725
00726
00727 static const char *cc1_options =
00728 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
00729 %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
00730 -auxbase%{c|S:%{o*:-strip %*}%{!o*: %b}}%{!c:%{!S: %b}}\
00731 %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
00732 %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
00733 %{Qn:-fno-ident} %{--help:--help}\
00734 %{--target-help:--target-help}\
00735 %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
00736 %{fsyntax-only:-o %j} %{-param*}";
00737
00738 static const char *asm_options =
00739 "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
00740
00741 static const char *invoke_as =
00742 "%{!S:-o %{|!pipe:%g.s} |\n as %(asm_options) %{!pipe:%g.s} %A }";
00743
00744
00745
00746
00747 static struct obstack multilib_obstack;
00748 static const char *multilib_select;
00749 static const char *multilib_matches;
00750 static const char *multilib_defaults;
00751 static const char *multilib_exclusions;
00752 #include "multilib.h"
00753
00754
00755
00756 #ifndef MULTILIB_DEFAULTS
00757 #define MULTILIB_DEFAULTS { "" }
00758 #endif
00759
00760 static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
00761
00762 #ifndef DRIVER_SELF_SPECS
00763 #define DRIVER_SELF_SPECS ""
00764 #endif
00765
00766 static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
00767
00768 struct user_specs
00769 {
00770 struct user_specs *next;
00771 const char *filename;
00772 };
00773
00774 static struct user_specs *user_specs_head, *user_specs_tail;
00775
00776 #ifndef SWITCH_TAKES_ARG
00777 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
00778 #endif
00779
00780 #ifndef WORD_SWITCH_TAKES_ARG
00781 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
00782 #endif
00783
00784 #ifdef HAVE_TARGET_EXECUTABLE_SUFFIX
00785
00786 #define DEFAULT_SWITCH_CURTAILS_COMPILATION(CHAR) \
00787 ((CHAR) == 'c' || (CHAR) == 'S')
00788
00789 #ifndef SWITCH_CURTAILS_COMPILATION
00790 #define SWITCH_CURTAILS_COMPILATION(CHAR) \
00791 DEFAULT_SWITCH_CURTAILS_COMPILATION(CHAR)
00792 #endif
00793 #endif
00794
00795
00796
00797 struct compiler
00798 {
00799 const char *suffix;
00800
00801
00802 const char *spec;
00803
00804 const char *cpp_spec;
00805
00806
00807 };
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 static struct compiler *compilers;
00819
00820
00821
00822 static int n_compilers;
00823
00824
00825
00826 static const struct compiler default_compilers[] =
00827 {
00828
00829
00830
00831
00832 {".m", "#Objective-C", 0}, {".mi", "#Objective-C", 0},
00833 {".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0},
00834 {".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0},
00835 {".ii", "#C++", 0},
00836 {".ads", "#Ada", 0}, {".adb", "#Ada", 0},
00837 {".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0},
00838 {".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
00839 {".r", "#Ratfor", 0},
00840 {".p", "#Pascal", 0}, {".pas", "#Pascal", 0},
00841 {".java", "#Java", 0}, {".class", "#Java", 0},
00842 {".zip", "#Java", 0}, {".jar", "#Java", 0},
00843
00844 {".c", "@c", 0},
00845 {"@c",
00846
00847
00848 "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
00849 %{!E:%{!M:%{!MM:\
00850 %{traditional|ftraditional:\
00851 %eGNU C no longer supports -traditional without -E}\
00852 %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
00853 %(cpp_options) %{save-temps:%b.i} %{!save-temps:%g.i} \n\
00854 cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} %(cc1_options)}\
00855 %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
00856 cc1 %(cpp_unique_options) %(cc1_options)}}}\
00857 %{!fsyntax-only:%(invoke_as)}}}}", 0},
00858 {"-",
00859 "%{!E:%e-E required when input is from standard input}\
00860 %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
00861 {".h", "@c-header", 0},
00862 {"@c-header",
00863 "%{!E:%ecompilation of header file requested} \
00864 %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
00865 0},
00866 {".i", "@cpp-output", 0},
00867 {"@cpp-output",
00868 "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
00869 {".s", "@assembler", 0},
00870 {"@assembler",
00871 "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0},
00872 {".S", "@assembler-with-cpp", 0},
00873 {"@assembler-with-cpp",
00874 "%(trad_capable_cpp) -lang-asm %(cpp_options)\
00875 %{E|M|MM:%(cpp_debug_options)}\
00876 %{!M:%{!MM:%{!E:%{!S:-o %{|!pipe:%g.s} |\n\
00877 as %(asm_debug) %(asm_options) %{!pipe:%g.s} %A }}}}", 0},
00878 #include "specs.h"
00879
00880 {0, 0, 0}
00881 };
00882
00883
00884
00885 static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
00886
00887
00888
00889
00890 static int n_linker_options;
00891 static char **linker_options;
00892
00893
00894
00895
00896 static int n_assembler_options;
00897 static char **assembler_options;
00898
00899
00900
00901
00902 static int n_preprocessor_options;
00903 static char **preprocessor_options;
00904
00905
00906
00907
00908 struct option_map
00909 {
00910
00911 const char *const name;
00912
00913 const char *const equivalent;
00914
00915
00916
00917
00918
00919 const char *const arg_info;
00920 };
00921
00922
00923
00924
00925 static const struct option_map option_map[] =
00926 {
00927 {"--all-warnings", "-Wall", 0},
00928 {"--ansi", "-ansi", 0},
00929 {"--assemble", "-S", 0},
00930 {"--assert", "-A", "a"},
00931 {"--classpath", "-fclasspath=", "aj"},
00932 {"--bootclasspath", "-fbootclasspath=", "aj"},
00933 {"--CLASSPATH", "-fclasspath=", "aj"},
00934 {"--comments", "-C", 0},
00935 {"--comments-in-macros", "-CC", 0},
00936 {"--compile", "-c", 0},
00937 {"--debug", "-g", "oj"},
00938 {"--define-macro", "-D", "aj"},
00939 {"--dependencies", "-M", 0},
00940 {"--dump", "-d", "a"},
00941 {"--dumpbase", "-dumpbase", "a"},
00942 {"--entry", "-e", 0},
00943 {"--extra-warnings", "-W", 0},
00944 {"--for-assembler", "-Wa", "a"},
00945 {"--for-linker", "-Xlinker", "a"},
00946 {"--force-link", "-u", "a"},
00947 {"--imacros", "-imacros", "a"},
00948 {"--include", "-include", "a"},
00949 {"--include-barrier", "-I-", 0},
00950 {"--include-directory", "-I", "aj"},
00951 {"--include-directory-after", "-idirafter", "a"},
00952 {"--include-prefix", "-iprefix", "a"},
00953 {"--include-with-prefix", "-iwithprefix", "a"},
00954 {"--include-with-prefix-before", "-iwithprefixbefore", "a"},
00955 {"--include-with-prefix-after", "-iwithprefix", "a"},
00956 {"--language", "-x", "a"},
00957 {"--library-directory", "-L", "a"},
00958 {"--machine", "-m", "aj"},
00959 {"--machine-", "-m", "*j"},
00960 {"--no-integrated-cpp", "-no-integrated-cpp", 0},
00961 {"--no-line-commands", "-P", 0},
00962 {"--no-precompiled-includes", "-noprecomp", 0},
00963 {"--no-standard-includes", "-nostdinc", 0},
00964 {"--no-standard-libraries", "-nostdlib", 0},
00965 {"--no-warnings", "-w", 0},
00966 {"--optimize", "-O", "oj"},
00967 {"--output", "-o", "a"},
00968 {"--output-class-directory", "-foutput-class-dir=", "ja"},
00969 {"--param", "--param", "a"},
00970 {"--pedantic", "-pedantic", 0},
00971 {"--pedantic-errors", "-pedantic-errors", 0},
00972 {"--pie", "-pie", 0},
00973 {"--pipe", "-pipe", 0},
00974 {"--prefix", "-B", "a"},
00975 {"--preprocess", "-E", 0},
00976 {"--print-search-dirs", "-print-search-dirs", 0},
00977 {"--print-file-name", "-print-file-name=", "aj"},
00978 {"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
00979 {"--print-missing-file-dependencies", "-MG", 0},
00980 {"--print-multi-lib", "-print-multi-lib", 0},
00981 {"--print-multi-directory", "-print-multi-directory", 0},
00982 {"--print-multi-os-directory", "-print-multi-os-directory", 0},
00983 {"--print-prog-name", "-print-prog-name=", "aj"},
00984 {"--profile", "-p", 0},
00985 {"--profile-blocks", "-a", 0},
00986 {"--quiet", "-q", 0},
00987 {"--resource", "-fcompile-resource=", "aj"},
00988 {"--save-temps", "-save-temps", 0},
00989 {"--shared", "-shared", 0},
00990 {"--silent", "-q", 0},
00991 {"--specs", "-specs=", "aj"},
00992 {"--static", "-static", 0},
00993 {"--std", "-std=", "aj"},
00994 {"--symbolic", "-symbolic", 0},
00995 {"--target", "-b", "a"},
00996 {"--time", "-time", 0},
00997 {"--trace-includes", "-H", 0},
00998 {"--traditional", "-traditional", 0},
00999 {"--traditional-cpp", "-traditional-cpp", 0},
01000 {"--trigraphs", "-trigraphs", 0},
01001 {"--undefine-macro", "-U", "aj"},
01002 {"--use-version", "-V", "a"},
01003 {"--user-dependencies", "-MM", 0},
01004 {"--verbose", "-v", 0},
01005 {"--warn-", "-W", "*j"},
01006 {"--write-dependencies", "-MD", 0},
01007 {"--write-user-dependencies", "-MMD", 0},
01008 {"--", "-f", "*j"}
01009 };
01010
01011
01012 #ifdef TARGET_OPTION_TRANSLATE_TABLE
01013 static const struct {
01014 const char *const option_found;
01015 const char *const replacements;
01016 } target_option_translations[] =
01017 {
01018 TARGET_OPTION_TRANSLATE_TABLE,
01019 { 0, 0 }
01020 };
01021 #endif
01022
01023
01024
01025
01026
01027 static void
01028 translate_options (argcp, argvp)
01029 int *argcp;
01030 const char *const **argvp;
01031 {
01032 int i;
01033 int argc = *argcp;
01034 const char *const *argv = *argvp;
01035 int newvsize = (argc + 2) * 2 * sizeof (const char *);
01036 const char **newv =
01037 (const char **) xmalloc (newvsize);
01038 int newindex = 0;
01039
01040 i = 0;
01041 newv[newindex++] = argv[i++];
01042
01043 while (i < argc)
01044 {
01045 #ifdef TARGET_OPTION_TRANSLATE_TABLE
01046 int tott_idx;
01047
01048 for (tott_idx = 0;
01049 target_option_translations[tott_idx].option_found;
01050 tott_idx++)
01051 {
01052 if (strcmp (target_option_translations[tott_idx].option_found,
01053 argv[i]) == 0)
01054 {
01055 int spaces = 1;
01056 const char *sp;
01057 char *np;
01058
01059 for (sp = target_option_translations[tott_idx].replacements;
01060 *sp; sp++)
01061 {
01062 if (*sp == ' ')
01063 spaces ++;
01064 }
01065
01066 newvsize += spaces * sizeof (const char *);
01067 newv = (const char **) xrealloc (newv, newvsize);
01068
01069 sp = target_option_translations[tott_idx].replacements;
01070 np = xstrdup (sp);
01071
01072 while (1)
01073 {
01074 while (*np == ' ')
01075 np++;
01076 if (*np == 0)
01077 break;
01078 newv[newindex++] = np;
01079 while (*np != ' ' && *np)
01080 np++;
01081 if (*np == 0)
01082 break;
01083 *np++ = 0;
01084 }
01085
01086 i ++;
01087 break;
01088 }
01089 }
01090 if (target_option_translations[tott_idx].option_found)
01091 continue;
01092 #endif
01093
01094
01095 if (argv[i][0] == '-' && argv[i][1] == '-')
01096 {
01097 size_t j;
01098
01099 for (j = 0; j < ARRAY_SIZE (option_map); j++)
01100 {
01101 size_t optlen = strlen (option_map[j].name);
01102 size_t arglen = strlen (argv[i]);
01103 size_t complen = arglen > optlen ? optlen : arglen;
01104 const char *arginfo = option_map[j].arg_info;
01105
01106 if (arginfo == 0)
01107 arginfo = "";
01108
01109 if (!strncmp (argv[i], option_map[j].name, complen))
01110 {
01111 const char *arg = 0;
01112
01113 if (arglen < optlen)
01114 {
01115 size_t k;
01116 for (k = j + 1; k < ARRAY_SIZE (option_map); k++)
01117 if (strlen (option_map[k].name) >= arglen
01118 && !strncmp (argv[i], option_map[k].name, arglen))
01119 {
01120 error ("ambiguous abbreviation %s", argv[i]);
01121 break;
01122 }
01123
01124 if (k != ARRAY_SIZE (option_map))
01125 break;
01126 }
01127
01128 if (arglen > optlen)
01129 {
01130
01131 if (argv[i][optlen] == '=')
01132 arg = argv[i] + optlen + 1;
01133
01134
01135
01136 else if (strchr (arginfo, '*') != 0)
01137 arg = argv[i] + optlen;
01138
01139
01140
01141 else
01142 continue;
01143 }
01144
01145 else if (strchr (arginfo, '*') != 0)
01146 {
01147 error ("incomplete `%s' option", option_map[j].name);
01148 break;
01149 }
01150
01151
01152 if (strchr (arginfo, 'a') != 0)
01153 {
01154 if (arg == 0)
01155 {
01156 if (i + 1 == argc)
01157 {
01158 error ("missing argument to `%s' option",
01159 option_map[j].name);
01160 break;
01161 }
01162
01163 arg = argv[++i];
01164 }
01165 }
01166 else if (strchr (arginfo, '*') != 0)
01167 ;
01168 else if (strchr (arginfo, 'o') == 0)
01169 {
01170 if (arg != 0)
01171 error ("extraneous argument to `%s' option",
01172 option_map[j].name);
01173 arg = 0;
01174 }
01175
01176
01177 if (arg != 0 && strchr (arginfo, 'j') != 0)
01178 newv[newindex++] = concat (option_map[j].equivalent, arg,
01179 NULL);
01180 else if (arg != 0)
01181 {
01182 newv[newindex++] = option_map[j].equivalent;
01183 newv[newindex++] = arg;
01184 }
01185 else
01186 newv[newindex++] = option_map[j].equivalent;
01187
01188 break;
01189 }
01190 }
01191 i++;
01192 }
01193
01194
01195
01196 else if (argv[i][0] == '-')
01197 {
01198 const char *p = argv[i] + 1;
01199 int c = *p;
01200 int nskip = 1;
01201
01202 if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
01203 nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
01204 else if (WORD_SWITCH_TAKES_ARG (p))
01205 nskip += WORD_SWITCH_TAKES_ARG (p);
01206 else if ((c == 'B' || c == 'b' || c == 'x')
01207 && p[1] == 0)
01208 nskip += 1;
01209 else if (! strcmp (p, "Xlinker"))
01210 nskip += 1;
01211
01212
01213
01214
01215 if (nskip + i > argc)
01216 nskip = argc - i;
01217
01218 while (nskip > 0)
01219 {
01220 newv[newindex++] = argv[i++];
01221 nskip--;
01222 }
01223 }
01224 else
01225
01226 newv[newindex++] = argv[i++];
01227 }
01228
01229 newv[newindex] = 0;
01230
01231 *argvp = newv;
01232 *argcp = newindex;
01233 }
01234
01235 static char *
01236 skip_whitespace (p)
01237 char *p;
01238 {
01239 while (1)
01240 {
01241
01242
01243 if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
01244 return p + 1;
01245 else if (*p == '\n' || *p == ' ' || *p == '\t')
01246 p++;
01247 else if (*p == '#')
01248 {
01249 while (*p != '\n')
01250 p++;
01251 p++;
01252 }
01253 else
01254 break;
01255 }
01256
01257 return p;
01258 }
01259
01260
01261 struct prefix_list
01262 {
01263 const char *prefix;
01264 struct prefix_list *next;
01265 int require_machine_suffix;
01266
01267 int *used_flag_ptr;
01268 int priority;
01269 int os_multilib;
01270
01271 };
01272
01273 struct path_prefix
01274 {
01275 struct prefix_list *plist;
01276 int max_len;
01277 const char *name;
01278 };
01279
01280
01281
01282 static struct path_prefix exec_prefixes = { 0, 0, "exec" };
01283
01284
01285
01286 static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };
01287
01288
01289
01290 static struct path_prefix include_prefixes = { 0, 0, "include" };
01291
01292
01293
01294
01295 static const char *machine_suffix = 0;
01296
01297
01298
01299
01300 static const char *just_machine_suffix = 0;
01301
01302
01303
01304 static const char *gcc_exec_prefix;
01305
01306
01307
01308 #ifdef CROSS_COMPILE
01309 #undef MD_EXEC_PREFIX
01310 #undef MD_STARTFILE_PREFIX
01311 #undef MD_STARTFILE_PREFIX_1
01312 #endif
01313
01314
01315 #ifndef MD_EXEC_PREFIX
01316 #define MD_EXEC_PREFIX ""
01317 #endif
01318 #ifndef MD_STARTFILE_PREFIX
01319 #define MD_STARTFILE_PREFIX ""
01320 #endif
01321 #ifndef MD_STARTFILE_PREFIX_1
01322 #define MD_STARTFILE_PREFIX_1 ""
01323 #endif
01324
01325
01326
01327 #ifndef STANDARD_EXEC_PREFIX
01328 #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
01329 #endif
01330 #ifndef STANDARD_STARTFILE_PREFIX
01331 #define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
01332 #endif
01333 #ifndef TOOLDIR_BASE_PREFIX
01334 #define TOOLDIR_BASE_PREFIX "/usr/local/"
01335 #endif
01336 #ifndef STANDARD_BINDIR_PREFIX
01337 #define STANDARD_BINDIR_PREFIX "/usr/local/bin"
01338 #endif
01339
01340 static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
01341 static const char *const standard_exec_prefix_1 = "/usr/lib/gcc/";
01342 static const char *md_exec_prefix = MD_EXEC_PREFIX;
01343
01344 static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
01345 static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
01346 static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
01347 static const char *const standard_startfile_prefix_1 = "/lib/";
01348 static const char *const standard_startfile_prefix_2 = "/usr/lib/";
01349
01350 static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
01351 static const char *tooldir_prefix;
01352
01353 static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
01354
01355
01356
01357
01358 static const char *multilib_dir;
01359
01360
01361
01362
01363 static const char *multilib_os_dir;
01364
01365
01366
01367
01368
01369 struct spec_list
01370 {
01371
01372
01373 const char *name;
01374 const char *ptr;
01375
01376
01377
01378 const char **ptr_spec;
01379 struct spec_list *next;
01380 int name_len;
01381 int alloc_p;
01382 };
01383
01384 #define INIT_STATIC_SPEC(NAME,PTR) \
01385 { NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, 0 }
01386
01387
01388 static struct spec_list static_specs[] =
01389 {
01390 INIT_STATIC_SPEC ("asm", &asm_spec),
01391 INIT_STATIC_SPEC ("asm_debug", &asm_debug),
01392 INIT_STATIC_SPEC ("asm_final", &asm_final_spec),
01393 INIT_STATIC_SPEC ("asm_options", &asm_options),
01394 INIT_STATIC_SPEC ("invoke_as", &invoke_as),
01395 INIT_STATIC_SPEC ("cpp", &cpp_spec),
01396 INIT_STATIC_SPEC ("cpp_options", &cpp_options),
01397 INIT_STATIC_SPEC ("cpp_debug_options", &cpp_debug_options),
01398 INIT_STATIC_SPEC ("cpp_unique_options", &cpp_unique_options),
01399 INIT_STATIC_SPEC ("trad_capable_cpp", &trad_capable_cpp),
01400 INIT_STATIC_SPEC ("cc1", &cc1_spec),
01401 INIT_STATIC_SPEC ("cc1_options", &cc1_options),
01402 INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec),
01403 INIT_STATIC_SPEC ("link_gcc_c_sequence", &link_gcc_c_sequence_spec),
01404 INIT_STATIC_SPEC ("endfile", &endfile_spec),
01405 INIT_STATIC_SPEC ("link", &link_spec),
01406 INIT_STATIC_SPEC ("lib", &lib_spec),
01407 INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
01408 INIT_STATIC_SPEC ("startfile", &startfile_spec),
01409 INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
01410 INIT_STATIC_SPEC ("predefines", &cpp_predefines),
01411 INIT_STATIC_SPEC ("cross_compile", &cross_compile),
01412 INIT_STATIC_SPEC ("version", &compiler_version),
01413 INIT_STATIC_SPEC ("multilib", &multilib_select),
01414 INIT_STATIC_SPEC ("multilib_defaults", &multilib_defaults),
01415 INIT_STATIC_SPEC ("multilib_extra", &multilib_extra),
01416 INIT_STATIC_SPEC ("multilib_matches", &multilib_matches),
01417 INIT_STATIC_SPEC ("multilib_exclusions", &multilib_exclusions),
01418 INIT_STATIC_SPEC ("multilib_options", &multilib_options),
01419 INIT_STATIC_SPEC ("linker", &linker_name_spec),
01420 INIT_STATIC_SPEC ("link_libgcc", &link_libgcc_spec),
01421 INIT_STATIC_SPEC ("md_exec_prefix", &md_exec_prefix),
01422 INIT_STATIC_SPEC ("md_startfile_prefix", &md_startfile_prefix),
01423 INIT_STATIC_SPEC ("md_startfile_prefix_1", &md_startfile_prefix_1),
01424 INIT_STATIC_SPEC ("startfile_prefix_spec", &startfile_prefix_spec),
01425 };
01426
01427 #ifdef EXTRA_SPECS
01428
01429
01430 struct spec_list_1
01431 {
01432 const char *const name;
01433 const char *const ptr;
01434 };
01435
01436 static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
01437 static struct spec_list *extra_specs = (struct spec_list *) 0;
01438 #endif
01439
01440
01441
01442 static struct spec_list *specs = (struct spec_list *) 0;
01443
01444
01445
01446 static const struct spec_function static_spec_functions[] =
01447 {
01448 { "if-exists", if_exists_spec_function },
01449 { "if-exists-else", if_exists_else_spec_function },
01450 { 0, 0 }
01451 };
01452
01453 static int processing_spec_function;
01454
01455
01456
01457
01458 #ifdef ENABLE_SHARED_LIBGCC
01459 static void
01460 init_gcc_specs (obstack, shared_name, static_name, eh_name)
01461 struct obstack *obstack;
01462 const char *shared_name;
01463 const char *static_name;
01464 const char *eh_name;
01465 {
01466 char *buf;
01467
01468 buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
01469 "}%{!static:%{!static-libgcc:",
01470 "%{!shared:%{!shared-libgcc:", static_name, " ",
01471 eh_name, "}%{shared-libgcc:", shared_name, " ",
01472 static_name, "}}%{shared:",
01473 #ifdef LINK_EH_SPEC
01474 "%{shared-libgcc:", shared_name,
01475 "}%{!shared-libgcc:", static_name, "}",
01476 #else
01477 shared_name,
01478 #endif
01479 "}}}", NULL);
01480
01481 obstack_grow (obstack, buf, strlen (buf));
01482 free (buf);
01483 }
01484 #endif
01485
01486
01487
01488 static void
01489 init_spec ()
01490 {
01491 struct spec_list *next = (struct spec_list *) 0;
01492 struct spec_list *sl = (struct spec_list *) 0;
01493 int i;
01494
01495 if (specs)
01496 return;
01497
01498 if (verbose_flag)
01499 notice ("Using built-in specs.\n");
01500
01501 #ifdef EXTRA_SPECS
01502 extra_specs = (struct spec_list *)
01503 xcalloc (sizeof (struct spec_list), ARRAY_SIZE (extra_specs_1));
01504
01505 for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
01506 {
01507 sl = &extra_specs[i];
01508 sl->name = extra_specs_1[i].name;
01509 sl->ptr = extra_specs_1[i].ptr;
01510 sl->next = next;
01511 sl->name_len = strlen (sl->name);
01512 sl->ptr_spec = &sl->ptr;
01513 next = sl;
01514 }
01515 #endif
01516
01517
01518
01519 asm_debug = ASM_DEBUG_SPEC;
01520
01521 for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
01522 {
01523 sl = &static_specs[i];
01524 sl->next = next;
01525 next = sl;
01526 }
01527
01528 #ifdef ENABLE_SHARED_LIBGCC
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 {
01557 const char *p = libgcc_spec;
01558 int in_sep = 1;
01559
01560
01561
01562 while (*p)
01563 {
01564 if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
01565 {
01566 init_gcc_specs (&obstack,
01567 #ifdef NO_SHARED_LIBGCC_MULTILIB
01568 "-lgcc_s"
01569 #else
01570 "-lgcc_s%M"
01571 #endif
01572 #ifdef USE_LIBUNWIND_EXCEPTIONS
01573 " -lunwind"
01574 #endif
01575 ,
01576 "-lgcc",
01577 "-lgcc_eh");
01578 p += 5;
01579 in_sep = 0;
01580 }
01581 else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
01582 {
01583
01584
01585 init_gcc_specs (&obstack,
01586 #ifdef NO_SHARED_LIBGCC_MULTILIB
01587 "-lgcc_s"
01588 #else
01589 "-lgcc_s%M"
01590 #endif
01591 ,
01592 "libgcc.a%s",
01593 "libgcc_eh.a%s");
01594 p += 10;
01595 in_sep = 0;
01596 }
01597 else
01598 {
01599 obstack_1grow (&obstack, *p);
01600 in_sep = (*p == ' ');
01601 p += 1;
01602 }
01603 }
01604
01605 obstack_1grow (&obstack, '\0');
01606 libgcc_spec = obstack_finish (&obstack);
01607 }
01608 #endif
01609 #ifdef USE_AS_TRADITIONAL_FORMAT
01610
01611 {
01612 static const char tf[] = "--traditional-format ";
01613 obstack_grow (&obstack, tf, sizeof(tf) - 1);
01614 obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
01615 asm_spec = obstack_finish (&obstack);
01616 }
01617 #endif
01618 #ifdef LINK_EH_SPEC
01619
01620 obstack_grow (&obstack, LINK_EH_SPEC, sizeof(LINK_EH_SPEC) - 1);
01621 obstack_grow0 (&obstack, link_spec, strlen (link_spec));
01622 link_spec = obstack_finish (&obstack);
01623 #endif
01624
01625 specs = sl;
01626 }
01627
01628
01629
01630
01631
01632 static void
01633 set_spec (name, spec)
01634 const char *name;
01635 const char *spec;
01636 {
01637 struct spec_list *sl;
01638 const char *old_spec;
01639 int name_len = strlen (name);
01640 int i;
01641
01642
01643 if (!specs)
01644 {
01645 struct spec_list *next = (struct spec_list *) 0;
01646 for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
01647 {
01648 sl = &static_specs[i];
01649 sl->next = next;
01650 next = sl;
01651 }
01652 specs = sl;
01653 }
01654
01655
01656 for (sl = specs; sl; sl = sl->next)
01657 if (name_len == sl->name_len && !strcmp (sl->name, name))
01658 break;
01659
01660 if (!sl)
01661 {
01662
01663 sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
01664 sl->name = xstrdup (name);
01665 sl->name_len = name_len;
01666 sl->ptr_spec = &sl->ptr;
01667 sl->alloc_p = 0;
01668 *(sl->ptr_spec) = "";
01669 sl->next = specs;
01670 specs = sl;
01671 }
01672
01673 old_spec = *(sl->ptr_spec);
01674 *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
01675 ? concat (old_spec, spec + 1, NULL)
01676 : xstrdup (spec));
01677
01678 #ifdef DEBUG_SPECS
01679 if (verbose_flag)
01680 notice ("Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
01681 #endif
01682
01683
01684 if (old_spec && sl->alloc_p)
01685 free ((PTR) old_spec);
01686
01687 sl->alloc_p = 1;
01688 }
01689
01690
01691
01692
01693
01694 static const char **argbuf;
01695
01696
01697
01698 static int argbuf_length;
01699
01700
01701
01702 static int argbuf_index;
01703
01704
01705
01706
01707
01708 static struct temp_name {
01709 const char *suffix;
01710 int length;
01711 int unique;
01712 const char *filename;
01713 int filename_length;
01714 struct temp_name *next;
01715 } *temp_names;
01716
01717
01718
01719 static int execution_count;
01720
01721
01722
01723 static int signal_count;
01724
01725
01726
01727 static const char *programname;
01728
01729
01730
01731 static void
01732 alloc_args ()
01733 {
01734 argbuf_length = 10;
01735 argbuf = (const char **) xmalloc (argbuf_length * sizeof (const char *));
01736 }
01737
01738
01739
01740 static void
01741 clear_args ()
01742 {
01743 argbuf_index = 0;
01744 }
01745
01746
01747
01748
01749
01750
01751
01752
01753 static void
01754 store_arg (arg, delete_always, delete_failure)
01755 const char *arg;
01756 int delete_always, delete_failure;
01757 {
01758 if (argbuf_index + 1 == argbuf_length)
01759 argbuf
01760 = (const char **) xrealloc (argbuf,
01761 (argbuf_length *= 2) * sizeof (const char *));
01762
01763 argbuf[argbuf_index++] = arg;
01764 argbuf[argbuf_index] = 0;
01765
01766 if (delete_always || delete_failure)
01767 record_temp_file (arg, delete_always, delete_failure);
01768 }
01769
01770
01771
01772
01773
01774 static char *
01775 load_specs (filename)
01776 const char *filename;
01777 {
01778 int desc;
01779 int readlen;
01780 struct stat statbuf;
01781 char *buffer;
01782 char *buffer_p;
01783 char *specs;
01784 char *specs_p;
01785
01786 if (verbose_flag)
01787 notice ("Reading specs from %s\n", filename);
01788
01789
01790 desc = open (filename, O_RDONLY, 0);
01791 if (desc < 0)
01792 pfatal_with_name (filename);
01793 if (stat (filename, &statbuf) < 0)
01794 pfatal_with_name (filename);
01795
01796
01797 buffer = xmalloc ((unsigned) statbuf.st_size + 1);
01798 readlen = read (desc, buffer, (unsigned) statbuf.st_size);
01799 if (readlen < 0)
01800 pfatal_with_name (filename);
01801 buffer[readlen] = 0;
01802 close (desc);
01803
01804 specs = xmalloc (readlen + 1);
01805 specs_p = specs;
01806 for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
01807 {
01808 int skip = 0;
01809 char c = *buffer_p;
01810 if (c == '\r')
01811 {
01812 if (buffer_p > buffer && *(buffer_p - 1) == '\n')
01813 skip = 1;
01814 else if (*(buffer_p + 1) == '\n')
01815 skip = 1;
01816 else
01817 c = '\n';
01818 }
01819 if (! skip)
01820 *specs_p++ = c;
01821 }
01822 *specs_p = '\0';
01823
01824 free (buffer);
01825 return (specs);
01826 }
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 static void
01840 read_specs (filename, main_p)
01841 const char *filename;
01842 int main_p;
01843 {
01844 char *buffer;
01845 char *p;
01846
01847 buffer = load_specs (filename);
01848
01849
01850 p = buffer;
01851 while (1)
01852 {
01853 char *suffix;
01854 char *spec;
01855 char *in, *out, *p1, *p2, *p3;
01856
01857
01858 p = skip_whitespace (p);
01859 if (*p == 0)
01860 break;
01861
01862
01863
01864
01865 if (*p == '%' && !main_p)
01866 {
01867 p1 = p;
01868 while (*p && *p != '\n')
01869 p++;
01870
01871
01872 p++;
01873
01874 if (!strncmp (p1, "%include", sizeof ("%include") - 1)
01875 && (p1[sizeof "%include" - 1] == ' '
01876 || p1[sizeof "%include" - 1] == '\t'))
01877 {
01878 char *new_filename;
01879
01880 p1 += sizeof ("%include");
01881 while (*p1 == ' ' || *p1 == '\t')
01882 p1++;
01883
01884 if (*p1++ != '<' || p[-2] != '>')
01885 fatal ("specs %%include syntax malformed after %ld characters",
01886 (long) (p1 - buffer + 1));
01887
01888 p[-2] = '\0';
01889 new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
01890 read_specs (new_filename ? new_filename : p1, FALSE);
01891 continue;
01892 }
01893 else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
01894 && (p1[sizeof "%include_noerr" - 1] == ' '
01895 || p1[sizeof "%include_noerr" - 1] == '\t'))
01896 {
01897 char *new_filename;
01898
01899 p1 += sizeof "%include_noerr";
01900 while (*p1 == ' ' || *p1 == '\t')
01901 p1++;
01902
01903 if (*p1++ != '<' || p[-2] != '>')
01904 fatal ("specs %%include syntax malformed after %ld characters",
01905 (long) (p1 - buffer + 1));
01906
01907 p[-2] = '\0';
01908 new_filename = find_a_file (&startfile_prefixes, p1, R_OK, 0);
01909 if (new_filename)
01910 read_specs (new_filename, FALSE);
01911 else if (verbose_flag)
01912 notice ("could not find specs file %s\n", p1);
01913 continue;
01914 }
01915 else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
01916 && (p1[sizeof "%rename" - 1] == ' '
01917 || p1[sizeof "%rename" - 1] == '\t'))
01918 {
01919 int name_len;
01920 struct spec_list *sl;
01921 struct spec_list *newsl;
01922
01923
01924 p1 += sizeof "%rename";
01925 while (*p1 == ' ' || *p1 == '\t')
01926 p1++;
01927
01928 if (! ISALPHA ((unsigned char) *p1))
01929 fatal ("specs %%rename syntax malformed after %ld characters",
01930 (long) (p1 - buffer));
01931
01932 p2 = p1;
01933 while (*p2 && !ISSPACE ((unsigned char) *p2))
01934 p2++;
01935
01936 if (*p2 != ' ' && *p2 != '\t')
01937 fatal ("specs %%rename syntax malformed after %ld characters",
01938 (long) (p2 - buffer));
01939
01940 name_len = p2 - p1;
01941 *p2++ = '\0';
01942 while (*p2 == ' ' || *p2 == '\t')
01943 p2++;
01944
01945 if (! ISALPHA ((unsigned char) *p2))
01946 fatal ("specs %%rename syntax malformed after %ld characters",
01947 (long) (p2 - buffer));
01948
01949
01950 p3 = p2;
01951 while (*p3 && !ISSPACE ((unsigned char) *p3))
01952 p3++;
01953
01954 if (p3 != p - 1)
01955 fatal ("specs %%rename syntax malformed after %ld characters",
01956 (long) (p3 - buffer));
01957 *p3 = '\0';
01958
01959 for (sl = specs; sl; sl = sl->next)
01960 if (name_len == sl->name_len && !strcmp (sl->name, p1))
01961 break;
01962
01963 if (!sl)
01964 fatal ("specs %s spec was not found to be renamed", p1);
01965
01966 if (strcmp (p1, p2) == 0)
01967 continue;
01968
01969 for (newsl = specs; newsl; newsl = newsl->next)
01970 if (strcmp (newsl->name, p2) == 0)
01971 fatal ("%s: attempt to rename spec '%s' to already defined spec '%s'",
01972 filename, p1, p2);
01973
01974 if (verbose_flag)
01975 {
01976 notice ("rename spec %s to %s\n", p1, p2);
01977 #ifdef DEBUG_SPECS
01978 notice ("spec is '%s'\n\n", *(sl->ptr_spec));
01979 #endif
01980 }
01981
01982 set_spec (p2, *(sl->ptr_spec));
01983 if (sl->alloc_p)
01984 free ((PTR) *(sl->ptr_spec));
01985
01986 *(sl->ptr_spec) = "";
01987 sl->alloc_p = 0;
01988 continue;
01989 }
01990 else
01991 fatal ("specs unknown %% command after %ld characters",
01992 (long) (p1 - buffer));
01993 }
01994
01995
01996 p1 = p;
01997 while (*p1 && *p1 != ':' && *p1 != '\n')
01998 p1++;
01999
02000
02001 if (*p1 != ':')
02002 fatal ("specs file malformed after %ld characters",
02003 (long) (p1 - buffer));
02004
02005
02006 p2 = p1;
02007 while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
02008 p2--;
02009
02010
02011 suffix = save_string (p, p2 - p);
02012
02013 p = skip_whitespace (p1 + 1);
02014 if (p[1] == 0)
02015 fatal ("specs file malformed after %ld characters",
02016 (long) (p - buffer));
02017
02018 p1 = p;
02019
02020 while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
02021 p1++;
02022
02023
02024 spec = save_string (p, p1 - p);
02025 p = p1;
02026
02027
02028 in = spec;
02029 out = spec;
02030 while (*in != 0)
02031 {
02032 if (in[0] == '\\' && in[1] == '\n')
02033 in += 2;
02034 else if (in[0] == '#')
02035 while (*in && *in != '\n')
02036 in++;
02037
02038 else
02039 *out++ = *in++;
02040 }
02041 *out = 0;
02042
02043 if (suffix[0] == '*')
02044 {
02045 if (! strcmp (suffix, "*link_command"))
02046 link_command_spec = spec;
02047 else
02048 set_spec (suffix + 1, spec);
02049 }
02050 else
02051 {
02052
02053 compilers
02054 = ((struct compiler *)
02055 xrealloc (compilers,
02056 (n_compilers + 2) * sizeof (struct compiler)));
02057
02058 compilers[n_compilers].suffix = suffix;
02059 compilers[n_compilers].spec = spec;
02060 n_compilers++;
02061 memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
02062 }
02063
02064 if (*suffix == 0)
02065 link_command_spec = spec;
02066 }
02067
02068 if (link_command_spec == 0)
02069 fatal ("spec file has no spec for linking");
02070 }
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086 static const char *temp_filename;
02087
02088
02089
02090 static int temp_filename_length;
02091
02092
02093
02094 struct temp_file
02095 {
02096 const char *name;
02097 struct temp_file *next;
02098 };
02099
02100
02101 static struct temp_file *always_delete_queue;
02102
02103 static struct temp_file *failure_delete_queue;
02104
02105
02106
02107
02108
02109
02110
02111 void
02112 record_temp_file (filename, always_delete, fail_delete)
02113 const char *filename;
02114 int always_delete;
02115 int fail_delete;
02116 {
02117 char *const name = xstrdup (filename);
02118
02119 if (always_delete)
02120 {
02121 struct temp_file *temp;
02122 for (temp = always_delete_queue; temp; temp = temp->next)
02123 if (! strcmp (name, temp->name))
02124 goto already1;
02125
02126 temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
02127 temp->next = always_delete_queue;
02128 temp->name = name;
02129 always_delete_queue = temp;
02130
02131 already1:;
02132 }
02133
02134 if (fail_delete)
02135 {
02136 struct temp_file *temp;
02137 for (temp = failure_delete_queue; temp; temp = temp->next)
02138 if (! strcmp (name, temp->name))
02139 goto already2;
02140
02141 temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
02142 temp->next = failure_delete_queue;
02143 temp->name = name;
02144 failure_delete_queue = temp;
02145
02146 already2:;
02147 }
02148 }
02149
02150
02151
02152 static void
02153 delete_if_ordinary (name)
02154 const char *name;
02155 {
02156 struct stat st;
02157 #ifdef DEBUG
02158 int i, c;
02159
02160 printf ("Delete %s? (y or n) ", name);
02161 fflush (stdout);
02162 i = getchar ();
02163 if (i != '\n')
02164 while ((c = getchar ()) != '\n' && c != EOF)
02165 ;
02166
02167 if (i == 'y' || i == 'Y')
02168 #endif
02169 if (stat (name, &st) >= 0 && S_ISREG (st.st_mode))
02170 if (unlink (name) < 0)
02171 if (verbose_flag)
02172 perror_with_name (name);
02173 }
02174
02175 static void
02176 delete_temp_files ()
02177 {
02178 struct temp_file *temp;
02179
02180 for (temp = always_delete_queue; temp; temp = temp->next)
02181 delete_if_ordinary (temp->name);
02182 always_delete_queue = 0;
02183 }
02184
02185
02186
02187 static void
02188 delete_failure_queue ()
02189 {
02190 struct temp_file *temp;
02191
02192 for (temp = failure_delete_queue; temp; temp = temp->next)
02193 delete_if_ordinary (temp->name);
02194 }
02195
02196 static void
02197 clear_failure_queue ()
02198 {
02199 failure_delete_queue = 0;
02200 }
02201
02202
02203
02204
02205
02206
02207
02208 static char *
02209 build_search_list (paths, prefix, check_dir_p)
02210 struct path_prefix *paths;
02211 const char *prefix;
02212 int check_dir_p;
02213 {
02214 int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
02215 int just_suffix_len
02216 = (just_machine_suffix) ? strlen (just_machine_suffix) : 0;
02217 int first_time = TRUE;
02218 struct prefix_list *pprefix;
02219
02220 obstack_grow (&collect_obstack, prefix, strlen (prefix));
02221 obstack_1grow (&collect_obstack, '=');
02222
02223 for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next)
02224 {
02225 int len = strlen (pprefix->prefix);
02226
02227 if (machine_suffix
02228 && (! check_dir_p
02229 || is_directory (pprefix->prefix, machine_suffix, 0)))
02230 {
02231 if (!first_time)
02232 obstack_1grow (&collect_obstack, PATH_SEPARATOR);
02233
02234 first_time = FALSE;
02235 obstack_grow (&collect_obstack, pprefix->prefix, len);
02236 obstack_grow (&collect_obstack, machine_suffix, suffix_len);
02237 }
02238
02239 if (just_machine_suffix
02240 && pprefix->require_machine_suffix == 2
02241 && (! check_dir_p
02242 || is_directory (pprefix->prefix, just_machine_suffix, 0)))
02243 {
02244 if (! first_time)
02245 obstack_1grow (&collect_obstack, PATH_SEPARATOR);
02246
02247 first_time = FALSE;
02248 obstack_grow (&collect_obstack, pprefix->prefix, len);
02249 obstack_grow (&collect_obstack, just_machine_suffix,
02250 just_suffix_len);
02251 }
02252
02253 if (! pprefix->require_machine_suffix)
02254 {
02255 if (! first_time)
02256 obstack_1grow (&collect_obstack, PATH_SEPARATOR);
02257
02258 first_time = FALSE;
02259 obstack_grow (&collect_obstack, pprefix->prefix, len);
02260 }
02261 }
02262
02263 obstack_1grow (&collect_obstack, '\0');
02264 return obstack_finish (&collect_obstack);
02265 }
02266
02267
02268
02269
02270 static void
02271 putenv_from_prefixes (paths, env_var)
02272 struct path_prefix *paths;
02273 const char *env_var;
02274 {
02275 putenv (build_search_list (paths, env_var, 1));
02276 }
02277
02278
02279
02280
02281 static int
02282 access_check (name, mode)
02283 const char *name;
02284 int mode;
02285 {
02286 if (mode == X_OK)
02287 {
02288 struct stat st;
02289
02290 if (stat (name, &st) < 0
02291 || S_ISDIR (st.st_mode))
02292 return -1;
02293 }
02294
02295 return access (name, mode);
02296 }
02297
02298
02299
02300
02301
02302 static char *
02303 find_a_file (pprefix, name, mode, multilib)
02304 struct path_prefix *pprefix;
02305 const char *name;
02306 int mode, multilib;
02307 {
02308 char *temp;
02309 const char *const file_suffix =
02310 ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
02311 struct prefix_list *pl;
02312 int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1;
02313 const char *multilib_name, *multilib_os_name;
02314
02315 #ifdef DEFAULT_ASSEMBLER
02316 if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
02317 return xstrdup (DEFAULT_ASSEMBLER);
02318 #endif
02319
02320 #ifdef DEFAULT_LINKER
02321 if (! strcmp(name, "ld") && access (DEFAULT_LINKER, mode) == 0)
02322 return xstrdup (DEFAULT_LINKER);
02323 #endif
02324
02325 if (machine_suffix)
02326 len += strlen (machine_suffix);
02327
02328 multilib_name = name;
02329 multilib_os_name = name;
02330 if (multilib && multilib_os_dir)
02331 {
02332 int len1 = multilib_dir ? strlen (multilib_dir) + 1 : 0;
02333 int len2 = strlen (multilib_os_dir) + 1;
02334
02335 len += len1 > len2 ? len1 : len2;
02336 if (multilib_dir)
02337 multilib_name = ACONCAT ((multilib_dir, dir_separator_str, name,
02338 NULL));
02339 if (strcmp (multilib_os_dir, ".") != 0)
02340 multilib_os_name = ACONCAT ((multilib_os_dir, dir_separator_str, name,
02341 NULL));
02342 }
02343
02344 temp = xmalloc (len);
02345
02346
02347
02348 if (IS_ABSOLUTE_PATHNAME (name))
02349 {
02350 if (access (name, mode) == 0)
02351 {
02352 strcpy (temp, name);
02353 return temp;
02354 }
02355 }
02356 else
02357 for (pl = pprefix->plist; pl; pl = pl->next)
02358 {
02359 const char *this_name
02360 = pl->os_multilib ? multilib_os_name : multilib_name;
02361
02362 if (machine_suffix)
02363 {
02364
02365
02366 if (file_suffix[0] != 0)
02367 {
02368 strcpy (temp, pl->prefix);
02369 strcat (temp, machine_suffix);
02370 strcat (temp, multilib_name);
02371 strcat (temp, file_suffix);
02372 if (access_check (temp, mode) == 0)
02373 {
02374 if (pl->used_flag_ptr != 0)
02375 *pl->used_flag_ptr = 1;
02376 return temp;
02377 }
02378 }
02379
02380
02381 strcpy (temp, pl->prefix);
02382 strcat (temp, machine_suffix);
02383 strcat (temp, multilib_name);
02384 if (access_check (temp, mode) == 0)
02385 {
02386 if (pl->used_flag_ptr != 0)
02387 *pl->used_flag_ptr = 1;
02388 return temp;
02389 }
02390 }
02391
02392
02393
02394 if (just_machine_suffix && pl->require_machine_suffix == 2)
02395 {
02396
02397
02398 if (file_suffix[0] != 0)
02399 {
02400 strcpy (temp, pl->prefix);
02401 strcat (temp, just_machine_suffix);
02402 strcat (temp, multilib_name);
02403 strcat (temp, file_suffix);
02404 if (access_check (temp, mode) == 0)
02405 {
02406 if (pl->used_flag_ptr != 0)
02407 *pl->used_flag_ptr = 1;
02408 return temp;
02409 }
02410 }
02411
02412 strcpy (temp, pl->prefix);
02413 strcat (temp, just_machine_suffix);
02414 strcat (temp, multilib_name);
02415 if (access_check (temp, mode) == 0)
02416 {
02417 if (pl->used_flag_ptr != 0)
02418 *pl->used_flag_ptr = 1;
02419 return temp;
02420 }
02421 }
02422
02423
02424
02425 if (! pl->require_machine_suffix)
02426 {
02427
02428
02429 if (file_suffix[0] != 0)
02430 {
02431 strcpy (temp, pl->prefix);
02432 strcat (temp, this_name);
02433 strcat (temp, file_suffix);
02434 if (access_check (temp, mode) == 0)
02435 {
02436 if (pl->used_flag_ptr != 0)
02437 *pl->used_flag_ptr = 1;
02438 return temp;
02439 }
02440 }
02441
02442 strcpy (temp, pl->prefix);
02443 strcat (temp, this_name);
02444 if (access_check (temp, mode) == 0)
02445 {
02446 if (pl->used_flag_ptr != 0)
02447 *pl->used_flag_ptr = 1;
02448 return temp;
02449 }
02450 }
02451 }
02452
02453 free (temp);
02454 return 0;
02455 }
02456
02457
02458
02459
02460 enum path_prefix_priority
02461 {
02462 PREFIX_PRIORITY_B_OPT,
02463 PREFIX_PRIORITY_LAST
02464 };
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480 static void
02481 add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
02482 warn, os_multilib)
02483 struct path_prefix *pprefix;
02484 const char *prefix;
02485 const char *component;
02486 int priority;
02487 int require_machine_suffix;
02488 int *warn;
02489 int os_multilib;
02490 {
02491 struct prefix_list *pl, **prev;
02492 int len;
02493
02494 for (prev = &pprefix->plist;
02495 (*prev) != NULL && (*prev)->priority <= priority;
02496 prev = &(*prev)->next)
02497 ;
02498
02499
02500
02501 prefix = update_path (prefix, component);
02502 len = strlen (prefix);
02503 if (len > pprefix->max_len)
02504 pprefix->max_len = len;
02505
02506 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
02507 pl->prefix = prefix;
02508 pl->require_machine_suffix = require_machine_suffix;
02509 pl->used_flag_ptr = warn;
02510 pl->priority = priority;
02511 pl->os_multilib = os_multilib;
02512 if (warn)
02513 *warn = 0;
02514
02515
02516 pl->next = (*prev);
02517 (*prev) = pl;
02518 }
02519
02520
02521
02522
02523
02524
02525
02526 static int
02527 execute ()
02528 {
02529 int i;
02530 int n_commands;
02531 char *string;
02532 struct command
02533 {
02534 const char *prog;
02535 const char **argv;
02536 int pid;
02537 };
02538
02539 struct command *commands;
02540
02541 if (processing_spec_function)
02542 abort ();
02543
02544
02545 for (n_commands = 1, i = 0; i < argbuf_index; i++)
02546 if (strcmp (argbuf[i], "|") == 0)
02547 n_commands++;
02548
02549
02550 commands = (struct command *) alloca (n_commands * sizeof (struct command));
02551
02552
02553
02554
02555
02556 commands[0].prog = argbuf[0];
02557 commands[0].argv = &argbuf[0];
02558 string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, 0);
02559
02560 if (string)
02561 commands[0].argv[0] = string;
02562
02563 for (n_commands = 1, i = 0; i < argbuf_index; i++)
02564 if (strcmp (argbuf[i], "|") == 0)
02565 {
02566 #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
02567 fatal ("-pipe not supported");
02568 #endif
02569 argbuf[i] = 0;
02570 commands[n_commands].prog = argbuf[i + 1];
02571 commands[n_commands].argv = &argbuf[i + 1];
02572 string = find_a_file (&exec_prefixes, commands[n_commands].prog,
02573 X_OK, 0);
02574 if (string)
02575 commands[n_commands].argv[0] = string;
02576 n_commands++;
02577 }
02578
02579 argbuf[argbuf_index] = 0;
02580
02581
02582
02583 if (verbose_flag)
02584 {
02585
02586 if (print_help_list)
02587 fputc ('\n', stderr);
02588
02589
02590 for (i = 0; i < n_commands; i++)
02591 {
02592 const char *const *j;
02593
02594 if (verbose_only_flag)
02595 {
02596 for (j = commands[i].argv; *j; j++)
02597 {
02598 const char *p;
02599 fprintf (stderr, " \"");
02600 for (p = *j; *p; ++p)
02601 {
02602 if (*p == '"' || *p == '\\' || *p == '$')
02603 fputc ('\\', stderr);
02604 fputc (*p, stderr);
02605 }
02606 fputc ('"', stderr);
02607 }
02608 }
02609 else
02610 for (j = commands[i].argv; *j; j++)
02611 fprintf (stderr, " %s", *j);
02612
02613
02614 if (i + 1 != n_commands)
02615 fprintf (stderr, " |");
02616 fprintf (stderr, "\n");
02617 }
02618 fflush (stderr);
02619 if (verbose_only_flag != 0)
02620 return 0;
02621 #ifdef DEBUG
02622 notice ("\nGo ahead? (y or n) ");
02623 fflush (stderr);
02624 i = getchar ();
02625 if (i != '\n')
02626 while (getchar () != '\n')
02627 ;
02628
02629 if (i != 'y' && i != 'Y')
02630 return 0;
02631 #endif
02632 }
02633
02634 #ifdef ENABLE_VALGRIND_CHECKING
02635
02636
02637
02638
02639 for (i = 0; i < n_commands; i++)
02640 {
02641 const char **argv;
02642 int argc;
02643 int j;
02644
02645 for (argc = 0; commands[i].argv[argc] != NULL; argc++)
02646 ;
02647
02648 argv = alloca ((argc + 3) * sizeof (char *));
02649
02650 argv[0] = VALGRIND_PATH;
02651 argv[1] = "-q";
02652 for (j = 2; j < argc + 2; j++)
02653 argv[j] = commands[i].argv[j - 2];
02654 argv[j] = NULL;
02655
02656 commands[i].argv = argv;
02657 commands[i].prog = argv[0];
02658 }
02659 #endif
02660
02661
02662
02663 for (i = 0; i < n_commands; i++)
02664 {
02665 char *errmsg_fmt, *errmsg_arg;
02666 const char *string = commands[i].argv[0];
02667
02668
02669
02670 commands[i].pid = pexecute (string, (char *const *) commands[i].argv,
02671 programname, temp_filename,
02672 &errmsg_fmt, &errmsg_arg,
02673 ((i == 0 ? PEXECUTE_FIRST : 0)
02674 | (i + 1 == n_commands ? PEXECUTE_LAST : 0)
02675 | (string == commands[i].prog
02676 ? PEXECUTE_SEARCH : 0)
02677 | (verbose_flag ? PEXECUTE_VERBOSE : 0)));
02678
02679 if (commands[i].pid == -1)
02680 pfatal_pexecute (errmsg_fmt, errmsg_arg);
02681
02682 if (string != commands[i].prog)
02683 free ((PTR) string);
02684 }
02685
02686 execution_count++;
02687
02688
02689
02690
02691
02692
02693
02694 {
02695 int ret_code = 0;
02696 #ifdef HAVE_GETRUSAGE
02697 struct timeval d;
02698 double ut = 0.0, st = 0.0;
02699 #endif
02700
02701 for (i = 0; i < n_commands;)
02702 {
02703 int j;
02704 int status;
02705 int pid;
02706
02707 pid = pwait (commands[i].pid, &status, 0);
02708 if (pid < 0)
02709 abort ();
02710
02711 #ifdef HAVE_GETRUSAGE
02712 if (report_times)
02713 {
02714
02715
02716
02717
02718 prus = rus;
02719 getrusage (RUSAGE_CHILDREN, &rus);
02720 d.tv_sec = rus.ru_utime.tv_sec - prus.ru_utime.tv_sec;
02721 d.tv_usec = rus.ru_utime.tv_usec - prus.ru_utime.tv_usec;
02722 ut = (double) d.tv_sec + (double) d.tv_usec / 1.0e6;
02723
02724 d.tv_sec = rus.ru_stime.tv_sec - prus.ru_stime.tv_sec;
02725 d.tv_usec = rus.ru_stime.tv_usec - prus.ru_stime.tv_usec;
02726 st = (double) d.tv_sec + (double) d.tv_usec / 1.0e6;
02727 }
02728 #endif
02729
02730 for (j = 0; j < n_commands; j++)
02731 if (commands[j].pid == pid)
02732 {
02733 i++;
02734 if (WIFSIGNALED (status))
02735 {
02736 #ifdef SIGPIPE
02737
02738
02739
02740
02741
02742
02743 if (WTERMSIG (status) == SIGPIPE
02744 && (signal_count || greatest_status >= MIN_FATAL_STATUS))
02745 ;
02746 else
02747 #endif
02748 fatal ("\
02749 Internal error: %s (program %s)\n\
02750 Please submit a full bug report.\n\
02751 See %s for instructions.",
02752 strsignal (WTERMSIG (status)), commands[j].prog,
02753 bug_report_url);
02754 signal_count++;
02755 ret_code = -1;
02756 }
02757 else if (WIFEXITED (status)
02758 && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
02759 {
02760 if (WEXITSTATUS (status) > greatest_status)
02761 greatest_status = WEXITSTATUS (status);
02762 ret_code = -1;
02763 }
02764 #ifdef HAVE_GETRUSAGE
02765 if (report_times && ut + st != 0)
02766 notice ("# %s %.2f %.2f\n", commands[j].prog, ut, st);
02767 #endif
02768 break;
02769 }
02770 }
02771 return ret_code;
02772 }
02773 }
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789 #define SWITCH_OK 0
02790 #define SWITCH_FALSE -1
02791 #define SWITCH_IGNORE -2
02792 #define SWITCH_LIVE 1
02793
02794 struct switchstr
02795 {
02796 const char *part1;
02797 const char **args;
02798 int live_cond;
02799 unsigned char validated;
02800 unsigned char ordering;
02801 };
02802
02803 static struct switchstr *switches;
02804
02805 static int n_switches;
02806
02807 struct infile
02808 {
02809 const char *name;
02810 const char *language;
02811 };
02812
02813
02814
02815 static struct infile *infiles;
02816
02817 int n_infiles;
02818
02819
02820
02821
02822 static int added_libraries;
02823
02824
02825
02826 const char **outfiles;
02827
02828
02829 static int warn_B;
02830
02831
02832 static int *warn_std_ptr = 0;
02833
02834 #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
02835
02836
02837
02838
02839
02840 static const char *
02841 convert_filename (name, do_exe, do_obj)
02842 const char *name;
02843 int do_exe ATTRIBUTE_UNUSED;
02844 int do_obj ATTRIBUTE_UNUSED;
02845 {
02846 #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
02847 int i;
02848 #endif
02849 int len;
02850
02851 if (name == NULL)
02852 return NULL;
02853
02854 len = strlen (name);
02855
02856 #ifdef HAVE_TARGET_OBJECT_SUFFIX
02857
02858 if (do_obj && len > 2
02859 && name[len - 2] == '.'
02860 && name[len - 1] == 'o')
02861 {
02862 obstack_grow (&obstack, name, len - 2);
02863 obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
02864 name = obstack_finish (&obstack);
02865 }
02866 #endif
02867
02868 #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
02869
02870
02871 if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || (len == 2 && name[0] == '-'))
02872 return name;
02873
02874 for (i = len - 1; i >= 0; i--)
02875 if (IS_DIR_SEPARATOR (name[i]))
02876 break;
02877
02878 for (i++; i < len; i++)
02879 if (name[i] == '.')
02880 return name;
02881
02882 obstack_grow (&obstack, name, len);
02883 obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
02884 strlen (TARGET_EXECUTABLE_SUFFIX));
02885 name = obstack_finish (&obstack);
02886 #endif
02887
02888 return name;
02889 }
02890 #endif
02891
02892
02893 static void
02894 display_help ()
02895 {
02896 printf (_("Usage: %s [options] file...\n"), programname);
02897 fputs (_("Options:\n"), stdout);
02898
02899 fputs (_(" -pass-exit-codes Exit with highest error code from a phase\n"), stdout);
02900 fputs (_(" --help Display this information\n"), stdout);
02901 fputs (_(" --target-help Display target specific command line options\n"), stdout);
02902 if (! verbose_flag)
02903 fputs (_(" (Use '-v --help' to display command line options of sub-processes)\n"), stdout);
02904 fputs (_(" -dumpspecs Display all of the built in spec strings\n"), stdout);
02905 fputs (_(" -dumpversion Display the version of the compiler\n"), stdout);
02906 fputs (_(" -dumpmachine Display the compiler's target processor\n"), stdout);
02907 fputs (_(" -print-search-dirs Display the directories in the compiler's search path\n"), stdout);
02908 fputs (_(" -print-libgcc-file-name Display the name of the compiler's companion library\n"), stdout);
02909 fputs (_(" -print-file-name=<lib> Display the full path to library <lib>\n"), stdout);
02910 fputs (_(" -print-prog-name=<prog> Display the full path to compiler component <prog>\n"), stdout);
02911 fputs (_(" -print-multi-directory Display the root directory for versions of libgcc\n"), stdout);
02912 fputs (_("\
02913 -print-multi-lib Display the mapping between command line options and\n\
02914 multiple library search directories\n"), stdout);
02915 fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
02916 fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout);
02917 fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout);
02918 fputs (_(" -Wl,<options> Pass comma-separated <options> on to the linker\n"), stdout);
02919 fputs (_(" -Xlinker <arg> Pass <arg> on to the linker\n"), stdout);
02920 fputs (_(" -save-temps Do not delete intermediate files\n"), stdout);
02921 fputs (_(" -pipe Use pipes rather than intermediate files\n"), stdout);
02922 fputs (_(" -time Time the execution of each subprocess\n"), stdout);
02923 fputs (_(" -specs=<file> Override built-in specs with the contents of <file>\n"), stdout);
02924 fputs (_(" -std=<standard> Assume that the input sources are for <standard>\n"), stdout);
02925 fputs (_(" -B <directory> Add <directory> to the compiler's search paths\n"), stdout);
02926 fputs (_(" -b <machine> Run gcc for target <machine>, if installed\n"), stdout);
02927 fputs (_(" -V <version> Run gcc version number <version>, if installed\n"), stdout);
02928 fputs (_(" -v Display the programs invoked by the compiler\n"), stdout);
02929 fputs (_(" -### Like -v but options quoted and commands not executed\n"), stdout);
02930 fputs (_(" -E Preprocess only; do not compile, assemble or link\n"), stdout);
02931 fputs (_(" -S Compile only; do not assemble or link\n"), stdout);
02932 fputs (_(" -c Compile and assemble, but do not link\n"), stdout);
02933 fputs (_(" -o <file> Place the output into <file>\n"), stdout);
02934 fputs (_("\
02935 -x <language> Specify the language of the following input files\n\
02936 Permissible languages include: c c++ assembler none\n\
02937 'none' means revert to the default behavior of\n\
02938 guessing the language based on the file's extension\n\
02939 "), stdout);
02940
02941 printf (_("\
02942 \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
02943 passed on to the various sub-processes invoked by %s. In order to pass\n\
02944 other options on to these processes the -W<letter> options must be used.\n\
02945 "), programname);
02946
02947
02948
02949 }
02950
02951 static void
02952 add_preprocessor_option (option, len)
02953 const char *option;
02954 int len;
02955 {
02956 n_preprocessor_options++;
02957
02958 if (! preprocessor_options)
02959 preprocessor_options
02960 = (char **) xmalloc (n_preprocessor_options * sizeof (char *));
02961 else
02962 preprocessor_options
02963 = (char **) xrealloc (preprocessor_options,
02964 n_preprocessor_options * sizeof (char *));
02965
02966 preprocessor_options [n_preprocessor_options - 1] =
02967 save_string (option, len);
02968 }
02969
02970 static void
02971 add_assembler_option (option, len)
02972 const char *option;
02973 int len;
02974 {
02975 n_assembler_options++;
02976
02977 if (! assembler_options)
02978 assembler_options
02979 = (char **) xmalloc (n_assembler_options * sizeof (char *));
02980 else
02981 assembler_options
02982 = (char **) xrealloc (assembler_options,
02983 n_assembler_options * sizeof (char *));
02984
02985 assembler_options [n_assembler_options - 1] = save_string (option, len);
02986 }
02987
02988 static void
02989 add_linker_option (option, len)
02990 const char *option;
02991 int len;
02992 {
02993 n_linker_options++;
02994
02995 if (! linker_options)
02996 linker_options
02997 = (char **) xmalloc (n_linker_options * sizeof (char *));
02998 else
02999 linker_options
03000 = (char **) xrealloc (linker_options,
03001 n_linker_options * sizeof (char *));
03002
03003 linker_options [n_linker_options - 1] = save_string (option, len);
03004 }
03005
03006
03007
03008
03009 static void
03010 process_command (argc, argv)
03011 int argc;
03012 const char *const *argv;
03013 {
03014 int i;
03015 const char *temp;
03016 char *temp1;
03017 const char *spec_lang = 0;
03018 int last_language_n_infiles;
03019 int have_c = 0;
03020 int have_o = 0;
03021 int lang_n_infiles = 0;
03022 #ifdef MODIFY_TARGET_NAME
03023 int is_modify_target_name;
03024 int j;
03025 #endif
03026
03027 GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
03028
03029 n_switches = 0;
03030 n_infiles = 0;
03031 added_libraries = 0;
03032
03033
03034
03035 compiler_version = temp1 = xstrdup (version_string);
03036
03037 for (; *temp1; ++temp1)
03038 {
03039 if (*temp1 == ' ')
03040 {
03041 *temp1 = '\0';
03042 break;
03043 }
03044 }
03045
03046
03047
03048 if (argc > 1 && argv[1][0] == '-'
03049 && (argv[1][1] == 'V' || argv[1][1] == 'b'))
03050 {
03051 const char *new_version = DEFAULT_TARGET_VERSION;
03052 const char *new_machine = DEFAULT_TARGET_MACHINE;
03053 const char *progname = argv[0];
03054 char **new_argv;
03055 char *new_argv0;
03056 int baselen;
03057
03058 while (argc > 1 && argv[1][0] == '-'
03059 && (argv[1][1] == 'V' || argv[1][1] == 'b'))
03060 {
03061 char opt = argv[1][1];
03062 const char *arg;
03063 if (argv[1][2] != '\0')
03064 {
03065 arg = argv[1] + 2;
03066 argc -= 1;
03067 argv += 1;
03068 }
03069 else if (argc > 2)
03070 {
03071 arg = argv[2];
03072 argc -= 2;
03073 argv += 2;
03074 }
03075 else
03076 fatal ("`-%c' option must have argument", opt);
03077 if (opt == 'V')
03078 new_version = arg;
03079 else
03080 new_machine = arg;
03081 }
03082
03083 for (baselen = strlen (progname); baselen > 0; baselen--)
03084 if (IS_DIR_SEPARATOR (progname[baselen-1]))
03085 break;
03086 new_argv0 = xmemdup (progname, baselen,
03087 baselen + concat_length (new_version, new_machine,
03088 "-gcc-", NULL) + 1);
03089 strcpy (new_argv0 + baselen, new_machine);
03090 strcat (new_argv0, "-gcc-");
03091 strcat (new_argv0, new_version);
03092
03093 new_argv = xmemdup (argv, (argc + 1) * sizeof (argv[0]),
03094 (argc + 1) * sizeof (argv[0]));
03095 new_argv[0] = new_argv0;
03096
03097 execvp (new_argv0, new_argv);
03098 fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
03099 }
03100
03101
03102
03103
03104 #ifndef VMS
03105
03106 if (!gcc_exec_prefix)
03107 {
03108 gcc_exec_prefix = make_relative_prefix (argv[0], standard_bindir_prefix,
03109 standard_exec_prefix);
03110 if (gcc_exec_prefix)
03111 putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
03112 }
03113 #endif
03114
03115 if (gcc_exec_prefix)
03116 {
03117 int len = strlen (gcc_exec_prefix);
03118
03119 if (len > (int) sizeof ("/lib/gcc-lib/") - 1
03120 && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
03121 {
03122 temp = gcc_exec_prefix + len - sizeof ("/lib/gcc-lib/") + 1;
03123 if (IS_DIR_SEPARATOR (*temp)
03124 && strncmp (temp + 1, "lib", 3) == 0
03125 && IS_DIR_SEPARATOR (temp[4])
03126 && strncmp (temp + 5, "gcc-lib", 7) == 0)
03127 len -= sizeof ("/lib/gcc-lib/") - 1;
03128 }
03129
03130 set_std_prefix (gcc_exec_prefix, len);
03131 add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC",
03132 PREFIX_PRIORITY_LAST, 0, NULL, 0);
03133 add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
03134 PREFIX_PRIORITY_LAST, 0, NULL, 0);
03135 }
03136
03137
03138
03139
03140 GET_ENVIRONMENT (temp, "COMPILER_PATH");
03141 if (temp)
03142 {
03143 const char *startp, *endp;
03144 char *nstore = (char *) alloca (strlen (temp) + 3);
03145
03146 startp = endp = temp;
03147 while (1)
03148 {
03149 if (*endp == PATH_SEPARATOR || *endp == 0)
03150 {
03151 strncpy (nstore, startp, endp - startp);
03152 if (endp == startp)
03153 strcpy (nstore, concat (".", dir_separator_str, NULL));
03154 else if (!IS_DIR_SEPARATOR (endp[-1]))
03155 {
03156 nstore[endp - startp] = DIR_SEPARATOR;
03157 nstore[endp - startp + 1] = 0;
03158 }
03159 else
03160 nstore[endp - startp] = 0;
03161 add_prefix (&exec_prefixes, nstore, 0,
03162 PREFIX_PRIORITY_LAST, 0, NULL, 0);
03163 add_prefix (&include_prefixes,
03164 concat (nstore, "include", NULL),
03165 0, PREFIX_PRIORITY_LAST, 0, NULL, 0);
03166 if (*endp == 0)
03167 break;
03168 endp = startp = endp + 1;
03169 }
03170 else
03171 endp++;
03172 }
03173 }
03174
03175 GET_ENVIRONMENT (temp, LIBRARY_PATH_ENV);
03176 if (temp && *cross_compile == '0')
03177 {
03178 const char *startp, *endp;
03179 char *nstore = (char *) alloca (strlen (temp) + 3);
03180
03181 startp = endp = temp;
03182 while (1)
03183 {
03184 if (*endp == PATH_SEPARATOR || *endp == 0)
03185 {
03186 strncpy (nstore, startp, endp - startp);
03187 if (endp == startp)
03188 strcpy (nstore, concat (".", dir_separator_str, NULL));
03189 else if (!IS_DIR_SEPARATOR (endp[-1]))
03190 {
03191 nstore[endp - startp] = DIR_SEPARATOR;
03192 nstore[endp - startp + 1] = 0;
03193 }
03194 else
03195 nstore[endp - startp] = 0;
03196 add_prefix (&startfile_prefixes, nstore, NULL,
03197 PREFIX_PRIORITY_LAST, 0, NULL, 1);
03198 if (*endp == 0)
03199 break;
03200 endp = startp = endp + 1;
03201 }
03202 else
03203 endp++;
03204 }
03205 }
03206
03207
03208 GET_ENVIRONMENT (temp, "LPATH");
03209 if (temp && *cross_compile == '0')
03210 {
03211 const char *startp, *endp;
03212 char *nstore = (char *) alloca (strlen (temp) + 3);
03213
03214 startp = endp = temp;
03215 while (1)
03216 {
03217 if (*endp == PATH_SEPARATOR || *endp == 0)
03218 {
03219 strncpy (nstore, startp, endp - startp);
03220 if (endp == startp)
03221 strcpy (nstore, concat (".", dir_separator_str, NULL));
03222 else if (!IS_DIR_SEPARATOR (endp[-1]))
03223 {
03224 nstore[endp - startp] = DIR_SEPARATOR;
03225 nstore[endp - startp + 1] = 0;
03226 }
03227 else
03228 nstore[endp - startp] = 0;
03229 add_prefix (&startfile_prefixes, nstore, NULL,
03230 PREFIX_PRIORITY_LAST, 0, NULL, 1);
03231 if (*endp == 0)
03232 break;
03233 endp = startp = endp + 1;
03234 }
03235 else
03236 endp++;
03237 }
03238 }
03239
03240
03241 translate_options (&argc, &argv);
03242
03243
03244 lang_specific_driver (&argc, &argv, &added_libraries);
03245
03246
03247
03248
03249
03250 for (i = 1; i < argc; i++)
03251 {
03252 if (! strcmp (argv[i], "-dumpspecs"))
03253 {
03254 struct spec_list *sl;
03255 init_spec ();
03256 for (sl = specs; sl; sl = sl->next)
03257 printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
03258 if (link_command_spec)
03259 printf ("*link_command:\n%s\n\n", link_command_spec);
03260 exit (0);
03261 }
03262 else if (! strcmp (argv[i], "-dumpversion"))
03263 {
03264 printf ("%s\n", spec_version);
03265 exit (0);
03266 }
03267 else if (! strcmp (argv[i], "-dumpmachine"))
03268 {
03269 printf ("%s\n", spec_machine);
03270 exit (0);
03271 }
03272 else if (strcmp (argv[i], "-fversion") == 0)
03273 {
03274
03275 printf (_("%s (GCC) %s\n"), programname, version_string);
03276 extern const char *hg_cset_id;
03277 printf (_("Changeset %s\n"), hg_cset_id);
03278 fputs (_("Copyright 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved.
03279 stdout);
03280 fputs (_("Copyright (C) 2003 Free Software Foundation, Inc.\n"),
03281 stdout);
03282 fputs (_("This is free software; see the source for copying conditions. There is NO\n\
03283 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
03284 stdout);
03285 exit (0);
03286 }
03287 else if (strcmp (argv[i], "-fhelp") == 0)
03288 {
03289 /* translate_options () has turned --help into -fhelp. */
03290 print_help_list = 1;
03291
03292 /* We will be passing a dummy file on to the sub-processes. */
03293 n_infiles++;
03294 n_switches++;
03295
03296 /* CPP driver cannot obtain switch from cc1_options. */
03297 if (is_cpp_driver)
03298 add_preprocessor_option ("--help", 6);
03299 add_assembler_option ("--help", 6);
03300 add_linker_option ("--help", 6);
03301 }
03302 else if (strcmp (argv[i], "-ftarget-help") == 0)
03303 {
03304 /* translate_options() has turned --target-help into -ftarget-help. */
03305 target_help_flag = 1;
03306
03307 /* We will be passing a dummy file on to the sub-processes. */
03308 n_infiles++;
03309 n_switches++;
03310
03311 /* CPP driver cannot obtain switch from cc1_options. */
03312 if (is_cpp_driver)
03313 add_preprocessor_option ("--target-help", 13);
03314 add_assembler_option ("--target-help", 13);
03315 add_linker_option ("--target-help", 13);
03316 }
03317 else if (! strcmp (argv[i], "-pass-exit-codes"))
03318 {
03319 pass_exit_codes = 1;
03320 n_switches++;
03321 }
03322 else if (! strcmp (argv[i], "-print-search-dirs"))
03323 print_search_dirs = 1;
03324 else if (! strcmp (argv[i], "-print-libgcc-file-name"))
03325 print_file_name = "libgcc.a";
03326 else if (! strncmp (argv[i], "-print-file-name=", 17))
03327 print_file_name = argv[i] + 17;
03328 else if (! strncmp (argv[i], "-print-prog-name=", 17))
03329 print_prog_name = argv[i] + 17;
03330 else if (! strcmp (argv[i], "-print-multi-lib"))
03331 print_multi_lib = 1;
03332 else if (! strcmp (argv[i], "-print-multi-directory"))
03333 print_multi_directory = 1;
03334 else if (! strcmp (argv[i], "-print-multi-os-directory"))
03335 print_multi_os_directory = 1;
03336 else if (! strncmp (argv[i], "-Wa,", 4))
03337 {
03338 int prev, j;
03339 /* Pass the rest of this option to the assembler. */
03340
03341 /* Split the argument at commas. */
03342 prev = 4;
03343 for (j = 4; argv[i][j]; j++)
03344 if (argv[i][j] == ',')
03345 {
03346 add_assembler_option (argv[i] + prev, j - prev);
03347 prev = j + 1;
03348 }
03349
03350 /* Record the part after the last comma. */
03351 add_assembler_option (argv[i] + prev, j - prev);
03352 }
03353 else if (! strncmp (argv[i], "-Wp,", 4))
03354 {
03355 int prev, j;
03356 /* Pass the rest of this option to the preprocessor. */
03357
03358 /* Split the argument at commas. */
03359 prev = 4;
03360 for (j = 4; argv[i][j]; j++)
03361 if (argv[i][j] == ',')
03362 {
03363 add_preprocessor_option (argv[i] + prev, j - prev);
03364 prev = j + 1;
03365 }
03366
03367 /* Record the part after the last comma. */
03368 add_preprocessor_option (argv[i] + prev, j - prev);
03369 }
03370 else if (argv[i][0] == '+' && argv[i][1] == 'e')
03371 /* The +e options to the C++ front-end. */
03372 n_switches++;
03373 else if (strncmp (argv[i], "-Wl,", 4) == 0)
03374 {
03375 int j;
03376 /* Split the argument at commas. */
03377 for (j = 3; argv[i][j]; j++)
03378 n_infiles += (argv[i][j] == ',');
03379 }
03380 else if (strcmp (argv[i], "-Xlinker") == 0)
03381 {
03382 if (i + 1 == argc)
03383 fatal ("argument to `-Xlinker' is missing");
03384
03385 n_infiles++;
03386 i++;
03387 }
03388 else if (strcmp (argv[i], "-l") == 0)
03389 {
03390 if (i + 1 == argc)
03391 fatal ("argument to `-l' is missing");
03392
03393 n_infiles++;
03394 i++;
03395 }
03396 else if (strncmp (argv[i], "-l", 2) == 0)
03397 n_infiles++;
03398 else if (strcmp (argv[i], "-save-temps") == 0)
03399 {
03400 save_temps_flag = 1;
03401 n_switches++;
03402 }
03403 else if (strcmp (argv[i], "-specs") == 0)
03404 {
03405 struct user_specs *user = (struct user_specs *)
03406 xmalloc (sizeof (struct user_specs));
03407 if (++i >= argc)
03408 fatal ("argument to `-specs' is missing");
03409
03410 user->next = (struct user_specs *) 0;
03411 user->filename = argv[i];
03412 if (user_specs_tail)
03413 user_specs_tail->next = user;
03414 else
03415 user_specs_head = user;
03416 user_specs_tail = user;
03417 }
03418 else if (strncmp (argv[i], "-specs=", 7) == 0)
03419 {
03420 struct user_specs *user = (struct user_specs *)
03421 xmalloc (sizeof (struct user_specs));
03422 if (strlen (argv[i]) == 7)
03423 fatal ("argument to `-specs=' is missing");
03424
03425 user->next = (struct user_specs *) 0;
03426 user->filename = argv[i] + 7;
03427 if (user_specs_tail)
03428 user_specs_tail->next = user;
03429 else
03430 user_specs_head = user;
03431 user_specs_tail = user;
03432 }
03433 else if (strcmp (argv[i], "-time") == 0)
03434 report_times = 1;
03435 else if (strcmp (argv[i], "-###") == 0)
03436 {
03437 /* This is similar to -v except that there is no execution
03438 of the commands and the echoed arguments are quoted. It
03439 is intended for use in shell scripts to capture the
03440 driver-generated command line. */
03441 verbose_only_flag++;
03442 verbose_flag++;
03443 }
03444 else if (argv[i][0] == '-' && argv[i][1] != 0)
03445 {
03446 const char *p = &argv[i][1];
03447 int c = *p;
03448
03449 switch (c)
03450 {
03451 case 'b':
03452 case 'V':
03453 fatal ("`-%c' must come at the start of the command line", c);
03454 break;
03455
03456 case 'B':
03457 {
03458 const char *value;
03459 int len;
03460
03461 if (p[1] == 0 && i + 1 == argc)
03462 fatal ("argument to `-B' is missing");
03463 if (p[1] == 0)
03464 value = argv[++i];
03465 else
03466 value = p + 1;
03467
03468 len = strlen (value);
03469
03470 /* Catch the case where the user has forgotten to append a
03471 directory separator to the path. Note, they may be using
03472 -B to add an executable name prefix, eg "i386-elf-", in
03473 order to distinguish between multiple installations of
03474 GCC in the same directory. Hence we must check to see
03475 if appending a directory separator actually makes a
03476 valid directory name. */
03477 if (! IS_DIR_SEPARATOR (value [len - 1])
03478 && is_directory (value, "", 0))
03479 {
03480 char *tmp = xmalloc (len + 2);
03481 strcpy (tmp, value);
03482 tmp[len] = DIR_SEPARATOR;
03483 tmp[++ len] = 0;
03484 value = tmp;
03485 }
03486
03487 /* As a kludge, if the arg is "[foo/]stageN/", just
03488 add "[foo/]include" to the include prefix. */
03489 if ((len == 7
03490 || (len > 7
03491 && (IS_DIR_SEPARATOR (value[len - 8]))))
03492 && strncmp (value + len - 7, "stage", 5) == 0
03493 && ISDIGIT (value[len - 2])
03494 && (IS_DIR_SEPARATOR (value[len - 1])))
03495 {
03496 if (len == 7)
03497 add_prefix (&include_prefixes, "include", NULL,
03498 PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
03499 else
03500 {
03501 char * string = xmalloc (len + 1);
03502
03503 strncpy (string, value, len - 7);
03504 strcpy (string + len - 7, "include");
03505 add_prefix (&include_prefixes, string, NULL,
03506 PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
03507 }
03508 }
03509
03510 add_prefix (&exec_prefixes, value, NULL,
03511 PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
03512 add_prefix (&startfile_prefixes, value, NULL,
03513 PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
03514 add_prefix (&include_prefixes, concat (value, "include", NULL),
03515 NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
03516 n_switches++;
03517 }
03518 break;
03519
03520 case 'v': /* Print our subcommands and print versions. */
03521 n_switches++;
03522 /* If they do anything other than exactly `-v', don't set
03523 verbose_flag; rather, continue on to give the error. */
03524 if (p[1] != 0)
03525 break;
03526 verbose_flag++;
03527 break;
03528
03529 case 'S':
03530 case 'c':
03531 if (p[1] == 0)
03532 {
03533 have_c = 1;
03534 n_switches++;
03535 break;
03536 }
03537 goto normal_switch;
03538
03539 case 'o':
03540 have_o = 1;
03541 #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
03542 if (! have_c)
03543 {
03544 int skip;
03545
03546 /* Forward scan, just in case -S or -c is specified
03547 after -o. */
03548 int j = i + 1;
03549 if (p[1] == 0)
03550 ++j;
03551 while (j < argc)
03552 {
03553 if (argv[j][0] == '-')
03554 {
03555 if (SWITCH_CURTAILS_COMPILATION (argv[j][1])
03556 && argv[j][2] == 0)
03557 {
03558 have_c = 1;
03559 break;
03560 }
03561 else if ((skip = SWITCH_TAKES_ARG (argv[j][1])))
03562 j += skip - (argv[j][2] != 0);
03563 else if ((skip = WORD_SWITCH_TAKES_ARG (argv[j] + 1)))
03564 j += skip;
03565 }
03566 j++;
03567 }
03568 }
03569 #endif
03570 #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
03571 if (p[1] == 0)
03572 argv[i + 1] = convert_filename (argv[i + 1], ! have_c, 0);
03573 else
03574 argv[i] = convert_filename (argv[i], ! have_c, 0);
03575 #endif
03576 goto normal_switch;
03577
03578 default:
03579 normal_switch:
03580
03581 #ifdef MODIFY_TARGET_NAME
03582 is_modify_target_name = 0;
03583
03584 for (j = 0; j < ARRAY_SIZE (modify_target); j++)
03585 if (! strcmp (argv[i], modify_target[j].sw))
03586 {
03587 char *new_name
03588 = (char *) xmalloc (strlen (modify_target[j].str)
03589 + strlen (spec_machine));
03590 const char *p, *r;
03591 char *q;
03592 int made_addition = 0;
03593
03594 is_modify_target_name = 1;
03595 for (p = spec_machine, q = new_name; *p != 0; )
03596 {
03597 if (modify_target[j].add_del == DELETE
03598 && (! strncmp (q, modify_target[j].str,
03599 strlen (modify_target[j].str))))
03600 p += strlen (modify_target[j].str);
03601 else if (modify_target[j].add_del == ADD
03602 && ! made_addition && *p == '-')
03603 {
03604 for (r = modify_target[j].str; *r != 0; )
03605 *q++ = *r++;
03606 made_addition = 1;
03607 }
03608
03609 *q++ = *p++;
03610 }
03611
03612 spec_machine = new_name;
03613 }
03614
03615 if (is_modify_target_name)
03616 break;
03617 #endif
03618
03619 n_switches++;
03620
03621 if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
03622 i += SWITCH_TAKES_ARG (c) - (p[1] != 0);
03623 else if (WORD_SWITCH_TAKES_ARG (p))
03624 i += WORD_SWITCH_TAKES_ARG (p);
03625 }
03626 }
03627 else
03628 {
03629 n_infiles++;
03630 lang_n_infiles++;
03631 }
03632 }
03633
03634 if (have_c && have_o && lang_n_infiles > 1)
03635 fatal ("cannot specify -o with -c or -S and multiple compilations");
03636
03637 /* Set up the search paths before we go looking for config files. */
03638
03639 /* These come before the md prefixes so that we will find gcc's subcommands
03640 (such as cpp) rather than those of the host system. */
03641 /* Use 2 as fourth arg meaning try just the machine as a suffix,
03642 as well as trying the machine and the version. */
03643 #ifndef OS2
03644 add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
03645 PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
03646 add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
03647 PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
03648 add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
03649 PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
03650 #endif
03651
03652 add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
03653 PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
03654 add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS",
03655 PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
03656
03657 tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
03658 dir_separator_str, NULL);
03659
03660 /* If tooldir is relative, base it on exec_prefixes. A relative
03661 tooldir lets us move the installed tree as a unit.
03662
03663 If GCC_EXEC_PREFIX is defined, then we want to add two relative
03664 directories, so that we can search both the user specified directory
03665 and the standard place. */
03666
03667 if (!IS_ABSOLUTE_PATHNAME (tooldir_prefix))
03668 {
03669 if (gcc_exec_prefix)
03670 {
03671 char *gcc_exec_tooldir_prefix
03672 = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
03673 spec_version, dir_separator_str, tooldir_prefix, NULL);
03674
03675 add_prefix (&exec_prefixes,
03676 concat (gcc_exec_tooldir_prefix, "bin",
03677 dir_separator_str, NULL),
03678 NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0);
03679 add_prefix (&startfile_prefixes,
03680 concat (gcc_exec_tooldir_prefix, "lib",
03681 dir_separator_str, NULL),
03682 NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
03683 }
03684
03685 tooldir_prefix = concat (standard_exec_prefix, spec_machine,
03686 dir_separator_str, spec_version,
03687 dir_separator_str, tooldir_prefix, NULL);
03688 }
03689
03690 add_prefix (&exec_prefixes,
03691 concat (tooldir_prefix, "bin", dir_separator_str, NULL),
03692 "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0);
03693 add_prefix (&startfile_prefixes,
03694 concat (tooldir_prefix, "lib", dir_separator_str, NULL),
03695 "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
03696
03697 /* More prefixes are enabled in main, after we read the specs file
03698 and determine whether this is cross-compilation or not. */
03699
03700 /* Then create the space for the vectors and scan again. */
03701
03702 switches = ((struct switchstr *)
03703 xmalloc ((n_switches + 1) * sizeof (struct switchstr)));
03704 infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile));
03705 n_switches = 0;
03706 n_infiles = 0;
03707 last_language_n_infiles = -1;
03708
03709 /* This, time, copy the text of each switch and store a pointer
03710 to the copy in the vector of switches.
03711 Store all the infiles in their vector. */
03712
03713 for (i = 1; i < argc; i++)
03714 {
03715 /* Just skip the switches that were handled by the preceding loop. */
03716 #ifdef MODIFY_TARGET_NAME
03717 is_modify_target_name = 0;
03718
03719 for (j = 0; j < ARRAY_SIZE (modify_target); j++)
03720 if (! strcmp (argv[i], modify_target[j].sw))
03721 is_modify_target_name = 1;
03722
03723 if (is_modify_target_name)
03724 ;
03725 else
03726 #endif
03727 if (! strncmp (argv[i], "-Wa,", 4))
03728 ;
03729 else if (! strncmp (argv[i], "-Wp,", 4))
03730 ;
03731 else if (! strcmp (argv[i], "-pass-exit-codes"))
03732 ;
03733 else if (! strcmp (argv[i], "-print-search-dirs"))
03734 ;
03735 else if (! strcmp (argv[i], "-print-libgcc-file-name"))
03736 ;
03737 else if (! strncmp (argv[i], "-print-file-name=", 17))
03738 ;
03739 else if (! strncmp (argv[i], "-print-prog-name=", 17))
03740 ;
03741 else if (! strcmp (argv[i], "-print-multi-lib"))
03742 ;
03743 else if (! strcmp (argv[i], "-print-multi-directory"))
03744 ;
03745 else if (! strcmp (argv[i], "-print-multi-os-directory"))
03746 ;
03747 else if (! strcmp (argv[i], "-ftarget-help"))
03748 ;
03749 else if (! strcmp (argv[i], "-fhelp"))
03750 ;
03751 else if (argv[i][0] == '+' && argv[i][1] == 'e')
03752 {
03753 /* Compensate for the +e options to the C++ front-end;
03754 they're there simply for cfront call-compatibility. We do
03755 some magic in default_compilers to pass them down properly.
03756 Note we deliberately start at the `+' here, to avoid passing
03757 -e0 or -e1 down into the linker. */
03758 switches[n_switches].part1 = &argv[i][0];
03759 switches[n_switches].args = 0;
03760 switches[n_switches].live_cond = SWITCH_OK;
03761 switches[n_switches].validated = 0;
03762 n_switches++;
03763 }
03764 else if (strncmp (argv[i], "-Wl,", 4) == 0)
03765 {
03766 int prev, j;
03767 /* Split the argument at commas. */
03768 prev = 4;
03769 for (j = 4; argv[i][j]; j++)
03770 if (argv[i][j] == ',')
03771 {
03772 infiles[n_infiles].language = "*";
03773 infiles[n_infiles++].name
03774 = save_string (argv[i] + prev, j - prev);
03775 prev = j + 1;
03776 }
03777 /* Record the part after the last comma. */
03778 infiles[n_infiles].language = "*";
03779 infiles[n_infiles++].name = argv[i] + prev;
03780 }
03781 else if (strcmp (argv[i], "-Xlinker") == 0)
03782 {
03783 infiles[n_infiles].language = "*";
03784 infiles[n_infiles++].name = argv[++i];
03785 }
03786 else if (strcmp (argv[i], "-l") == 0)
03787 { /* POSIX allows separation of -l and the lib arg;
03788 canonicalize by concatenating -l with its arg */
03789 infiles[n_infiles].language = "*";
03790 infiles[n_infiles++].name = concat ("-l", argv[++i], NULL);
03791 }
03792 else if (strncmp (argv[i], "-l", 2) == 0)
03793 {
03794 infiles[n_infiles].language = "*";
03795 infiles[n_infiles++].name = argv[i];
03796 }
03797 else if (strcmp (argv[i], "-specs") == 0)
03798 i++;
03799 else if (strncmp (argv[i], "-specs=", 7) == 0)
03800 ;
03801 else if (strcmp (argv[i], "-time") == 0)
03802 ;
03803 else if ((save_temps_flag || report_times)
03804 && strcmp (argv[i], "-pipe") == 0)
03805 {
03806 /* -save-temps overrides -pipe, so that temp files are produced */
03807 if (save_temps_flag)
03808 error ("warning: -pipe ignored because -save-temps specified");
03809 /* -time overrides -pipe because we can't get correct stats when
03810 multiple children are running at once. */
03811 else if (report_times)
03812 error ("warning: -pipe ignored because -time specified");
03813 }
03814 else if (strcmp (argv[i], "-###") == 0)
03815 ;
03816 else if (argv[i][0] == '-' && argv[i][1] != 0)
03817 {
03818 const char *p = &argv[i][1];
03819 int c = *p;
03820
03821 if (c == 'x')
03822 {
03823 if (p[1] == 0 && i + 1 == argc)
03824 fatal ("argument to `-x' is missing");
03825 if (p[1] == 0)
03826 spec_lang = argv[++i];
03827 else
03828 spec_lang = p + 1;
03829 if (! strcmp (spec_lang, "none"))
03830 /* Suppress the warning if -xnone comes after the last input
03831 file, because alternate command interfaces like g++ might
03832 find it useful to place -xnone after each input file. */
03833 spec_lang = 0;
03834 else
03835 last_language_n_infiles = n_infiles;
03836 continue;
03837 }
03838 switches[n_switches].part1 = p;
03839 /* Deal with option arguments in separate argv elements. */
03840 if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
03841 || WORD_SWITCH_TAKES_ARG (p))
03842 {
03843 int j = 0;
03844 int n_args = WORD_SWITCH_TAKES_ARG (p);
03845
03846 if (n_args == 0)
03847 {
03848 /* Count only the option arguments in separate argv elements. */
03849 n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
03850 }
03851 if (i + n_args >= argc)
03852 fatal ("argument to `-%s' is missing", p);
03853 switches[n_switches].args
03854 = (const char **) xmalloc ((n_args + 1) * sizeof(const char *));
03855 while (j < n_args)
03856 switches[n_switches].args[j++] = argv[++i];
03857 /* Null-terminate the vector. */
03858 switches[n_switches].args[j] = 0;
03859 }
03860 else if (strchr (switches_need_spaces, c))
03861 {
03862 /* On some systems, ld cannot handle some options without
03863 a space. So split the option from its argument. */
03864 char *part1 = (char *) xmalloc (2);
03865 part1[0] = c;
03866 part1[1] = '\0';
03867
03868 switches[n_switches].part1 = part1;
03869 switches[n_switches].args
03870 = (const char **) xmalloc (2 * sizeof (const char *));
03871 switches[n_switches].args[0] = xstrdup (p+1);
03872 switches[n_switches].args[1] = 0;
03873 }
03874 else
03875 switches[n_switches].args = 0;
03876
03877 switches[n_switches].live_cond = SWITCH_OK;
03878 switches[n_switches].validated = 0;
03879 switches[n_switches].ordering = 0;
03880 /* These are always valid, since gcc.c itself understands it. */
03881 if (!strcmp (p, "save-temps")
03882 || !strcmp (p, "static-libgcc")
03883 || !strcmp (p, "shared-libgcc"))
03884 switches[n_switches].validated = 1;
03885 else
03886 {
03887 char ch = switches[n_switches].part1[0];
03888 if (ch == 'B')
03889 switches[n_switches].validated = 1;
03890 }
03891 n_switches++;
03892 }
03893 else
03894 {
03895 #ifdef HAVE_TARGET_OBJECT_SUFFIX
03896 argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
03897 #endif
03898
03899 if (strcmp (argv[i], "-") != 0 && access (argv[i], F_OK) < 0)
03900 {
03901 perror_with_name (argv[i]);
03902 error_count++;
03903 }
03904 else
03905 {
03906 infiles[n_infiles].language = spec_lang;
03907 infiles[n_infiles++].name = argv[i];
03908 }
03909 }
03910 }
03911
03912 if (n_infiles == last_language_n_infiles && spec_lang != 0)
03913 error ("warning: `-x %s' after last input file has no effect", spec_lang);
03914
03915 /* Ensure we only invoke each subprocess once. */
03916 if (target_help_flag || print_help_list)
03917 {
03918 n_infiles = 1;
03919
03920 /* Create a dummy input file, so that we can pass --target-help on to
03921 the various sub-processes. */
03922 infiles[0].language = "c";
03923 infiles[0].name = "help-dummy";
03924
03925 if (target_help_flag)
03926 {
03927 switches[n_switches].part1 = "--target-help";
03928 switches[n_switches].args = 0;
03929 switches[n_switches].live_cond = SWITCH_OK;
03930 switches[n_switches].validated = 0;
03931
03932 n_switches++;
03933 }
03934
03935 if (print_help_list)
03936 {
03937 switches[n_switches].part1 = "--help";
03938 switches[n_switches].args = 0;
03939 switches[n_switches].live_cond = SWITCH_OK;
03940 switches[n_switches].validated = 0;
03941
03942 n_switches++;
03943 }
03944 }
03945
03946 switches[n_switches].part1 = 0;
03947 infiles[n_infiles].name = 0;
03948 }
03949
03950 /* Store switches not filtered out by %{<S} in spec in COLLECT_GCC_OPTIONS
03951 and place that in the environment. */
03952
03953 static void
03954 set_collect_gcc_options ()
03955 {
03956 int i;
03957 int first_time;
03958
03959 /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
03960 the compiler. */
03961 obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
03962 sizeof ("COLLECT_GCC_OPTIONS=") - 1);
03963
03964 first_time = TRUE;
03965 for (i = 0; (int) i < n_switches; i++)
03966 {
03967 const char *const *args;
03968 const char *p, *q;
03969 if (!first_time)
03970 obstack_grow (&collect_obstack, " ", 1);
03971
03972 first_time = FALSE;
03973
03974 /* Ignore elided switches. */
03975 if (switches[i].live_cond == SWITCH_IGNORE)
03976 continue;
03977
03978 obstack_grow (&collect_obstack, "'-", 2);
03979 q = switches[i].part1;
03980 while ((p = strchr (q, '\'')))
03981 {
03982 obstack_grow (&collect_obstack, q, p - q);
03983 obstack_grow (&collect_obstack, "'\\''", 4);
03984 q = ++p;
03985 }
03986 obstack_grow (&collect_obstack, q, strlen (q));
03987 obstack_grow (&collect_obstack, "'", 1);
03988
03989 for (args = switches[i].args; args && *args; args++)
03990 {
03991 obstack_grow (&collect_obstack, " '", 2);
03992 q = *args;
03993 while ((p = strchr (q, '\'')))
03994 {
03995 obstack_grow (&collect_obstack, q, p - q);
03996 obstack_grow (&collect_obstack, "'\\''", 4);
03997 q = ++p;
03998 }
03999 obstack_grow (&collect_obstack, q, strlen (q));
04000 obstack_grow (&collect_obstack, "'", 1);
04001 }
04002 }
04003 obstack_grow (&collect_obstack, "\0", 1);
04004 putenv (obstack_finish (&collect_obstack));
04005 }
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016 const char *input_filename;
04017 static int input_file_number;
04018 size_t input_filename_length;
04019 static int basename_length;
04020 static int suffixed_basename_length;
04021 static const char *input_basename;
04022 static const char *input_suffix;
04023 static struct stat input_stat;
04024 static int input_stat_set;
04025
04026
04027 static struct compiler *input_file_compiler;
04028
04029
04030
04031
04032
04033 static int arg_going;
04034
04035
04036
04037 static int delete_this_arg;
04038
04039
04040
04041 static int this_is_output_file;
04042
04043
04044
04045
04046 static int this_is_library_file;
04047
04048
04049 static int input_from_pipe;
04050
04051
04052
04053 static const char *suffix_subst;
04054
04055
04056
04057
04058 int
04059 do_spec (spec)
04060 const char *spec;
04061 {
04062 int value;
04063
04064 value = do_spec_2 (spec);
04065
04066
04067
04068 if (value == 0)
04069 {
04070 if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
04071 argbuf_index--;
04072
04073 set_collect_gcc_options ();
04074
04075 if (argbuf_index > 0)
04076 value = execute ();
04077 }
04078
04079 return value;
04080 }
04081
04082 static int
04083 do_spec_2 (spec)
04084 const char *spec;
04085 {
04086 clear_args ();
04087 arg_going = 0;
04088 delete_this_arg = 0;
04089 this_is_output_file = 0;
04090 this_is_library_file = 0;
04091 input_from_pipe = 0;
04092 suffix_subst = NULL;
04093
04094 return do_spec_1 (spec, 0, NULL);
04095 }
04096
04097
04098
04099
04100
04101 static void
04102 do_self_spec (spec)
04103 const char *spec;
04104 {
04105 do_spec_2 (spec);
04106 do_spec_1 (" ", 0, NULL);
04107
04108 if (argbuf_index > 0)
04109 {
04110 int i, first;
04111
04112 first = n_switches;
04113 n_switches += argbuf_index;
04114 switches = xrealloc (switches,
04115 sizeof (struct switchstr) * (n_switches + 1));
04116
04117 switches[n_switches] = switches[first];
04118 for (i = 0; i < argbuf_index; i++)
04119 {
04120 struct switchstr *sw;
04121
04122
04123 if (argbuf[i][0] != '-')
04124 abort ();
04125
04126 sw = &switches[i + first];
04127 sw->part1 = &argbuf[i][1];
04128 sw->args = 0;
04129 sw->live_cond = SWITCH_OK;
04130 sw->validated = 0;
04131 sw->ordering = 0;
04132 }
04133 }
04134 }
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148 static int
04149 do_spec_1 (spec, inswitch, soft_matched_part)
04150 const char *spec;
04151 int inswitch;
04152 const char *soft_matched_part;
04153 {
04154 const char *p = spec;
04155 int c;
04156 int i;
04157 const char *string;
04158 int value;
04159
04160 while ((c = *p++))
04161
04162
04163 switch (inswitch ? 'a' : c)
04164 {
04165 case '\n':
04166
04167
04168 if (arg_going)
04169 {
04170 obstack_1grow (&obstack, 0);
04171 string = obstack_finish (&obstack);
04172 if (this_is_library_file)
04173 string = find_file (string);
04174 store_arg (string, delete_this_arg, this_is_output_file);
04175 if (this_is_output_file)
04176 outfiles[input_file_number] = string;
04177 }
04178 arg_going = 0;
04179
04180 if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
04181 {
04182 for (i = 0; i < n_switches; i++)
04183 if (!strcmp (switches[i].part1, "pipe"))
04184 break;
04185
04186
04187
04188
04189 if (i < n_switches)
04190 {
04191 input_from_pipe = 1;
04192 switches[i].validated = 1;
04193 break;
04194 }
04195 else
04196 argbuf_index--;
04197 }
04198
04199 set_collect_gcc_options ();
04200
04201 if (argbuf_index > 0)
04202 {
04203 value = execute ();
04204 if (value)
04205 return value;
04206 }
04207
04208 clear_args ();
04209 arg_going = 0;
04210 delete_this_arg = 0;
04211 this_is_output_file = 0;
04212 this_is_library_file = 0;
04213 input_from_pipe = 0;
04214 break;
04215
04216 case '|':
04217
04218 if (arg_going)
04219 {
04220 obstack_1grow (&obstack, 0);
04221 string = obstack_finish (&obstack);
04222 if (this_is_library_file)
04223 string = find_file (string);
04224 store_arg (string, delete_this_arg, this_is_output_file);
04225 if (this_is_output_file)
04226 outfiles[input_file_number] = string;
04227 }
04228
04229
04230 obstack_1grow (&obstack, c);
04231 arg_going = 1;
04232 break;
04233
04234 case '\t':
04235 case ' ':
04236
04237 if (arg_going)
04238 {
04239 obstack_1grow (&obstack, 0);
04240 string = obstack_finish (&obstack);
04241 if (this_is_library_file)
04242 string = find_file (string);
04243 store_arg (string, delete_this_arg, this_is_output_file);
04244 if (this_is_output_file)
04245 outfiles[input_file_number] = string;
04246 }
04247
04248 arg_going = 0;
04249 delete_this_arg = 0;
04250 this_is_output_file = 0;
04251 this_is_library_file = 0;
04252 break;
04253
04254 case '%':
04255 switch (c = *p++)
04256 {
04257 case 0:
04258 fatal ("invalid specification! Bug in cc");
04259
04260 case 'b':
04261 obstack_grow (&obstack, input_basename, basename_length);
04262 arg_going = 1;
04263 break;
04264
04265 case 'B':
04266 obstack_grow (&obstack, input_basename, suffixed_basename_length);
04267 arg_going = 1;
04268 break;
04269
04270 case 'd':
04271 delete_this_arg = 2;
04272 break;
04273
04274
04275
04276
04277 case 'D':
04278 {
04279 struct prefix_list *pl = startfile_prefixes.plist;
04280 size_t bufsize = 100;
04281 char *buffer = (char *) xmalloc (bufsize);
04282 int idx;
04283
04284 for (; pl; pl = pl->next)
04285 {
04286 #ifdef RELATIVE_PREFIX_NOT_LINKDIR
04287
04288
04289
04290
04291
04292 if (!IS_ABSOLUTE_PATHNAME (pl->prefix))
04293 continue;
04294 #endif
04295
04296 if (multilib_dir != NULL
04297 || (pl->os_multilib && multilib_os_dir != NULL))
04298 {
04299 const char *multi_dir;
04300
04301 multi_dir = pl->os_multilib ? multilib_os_dir
04302 : multilib_dir;
04303 if (machine_suffix && multilib_dir)
04304 {
04305 if (strlen (pl->prefix) + strlen (machine_suffix)
04306 >= bufsize)
04307 bufsize = (strlen (pl->prefix)
04308 + strlen (machine_suffix)) * 2 + 1;
04309 buffer = (char *) xrealloc (buffer, bufsize);
04310 strcpy (buffer, pl->prefix);
04311 strcat (buffer, machine_suffix);
04312 if (is_directory (buffer, multilib_dir, 1))
04313 {
04314 do_spec_1 ("-L", 0, NULL);
04315 #ifdef SPACE_AFTER_L_OPTION
04316 do_spec_1 (" ", 0, NULL);
04317 #endif
04318 do_spec_1 (buffer, 1, NULL);
04319 do_spec_1 (multilib_dir, 1, NULL);
04320
04321 do_spec_1 (" ", 0, NULL);
04322 }
04323 }
04324 if (!pl->require_machine_suffix)
04325 {
04326 if (is_directory (pl->prefix, multi_dir, 1))
04327 {
04328 do_spec_1 ("-L", 0, NULL);
04329 #ifdef SPACE_AFTER_L_OPTION
04330 do_spec_1 (" ", 0, NULL);
04331 #endif
04332 do_spec_1 (pl->prefix, 1, NULL);
04333 do_spec_1 (multi_dir, 1, NULL);
04334
04335 do_spec_1 (" ", 0, NULL);
04336 }
04337 }
04338 }
04339 if (machine_suffix)
04340 {
04341 if (is_directory (pl->prefix, machine_suffix, 1))
04342 {
04343 do_spec_1 ("-L", 0, NULL);
04344 #ifdef SPACE_AFTER_L_OPTION
04345 do_spec_1 (" ", 0, NULL);
04346 #endif
04347 do_spec_1 (pl->prefix, 1, NULL);
04348
04349 if (strlen (machine_suffix) >= bufsize)
04350 bufsize = strlen (machine_suffix) * 2 + 1;
04351 buffer = (char *) xrealloc (buffer, bufsize);
04352 strcpy (buffer, machine_suffix);
04353 idx = strlen (buffer);
04354 if (IS_DIR_SEPARATOR (buffer[idx - 1]))
04355 buffer[idx - 1] = 0;
04356 do_spec_1 (buffer, 1, NULL);
04357
04358 do_spec_1 (" ", 0, NULL);
04359 }
04360 }
04361 if (!pl->require_machine_suffix)
04362 {
04363 if (is_directory (pl->prefix, "", 1))
04364 {
04365 do_spec_1 ("-L", 0, NULL);
04366 #ifdef SPACE_AFTER_L_OPTION
04367 do_spec_1 (" ", 0, NULL);
04368 #endif
04369
04370 if (strlen (pl->prefix) >= bufsize)
04371 bufsize = strlen (pl->prefix) * 2 + 1;
04372 buffer = (char *) xrealloc (buffer, bufsize);
04373 strcpy (buffer, pl->prefix);
04374 idx = strlen (buffer);
04375 if (IS_DIR_SEPARATOR (buffer[idx - 1]))
04376 buffer[idx - 1] = 0;
04377 do_spec_1 (buffer, 1, NULL);
04378
04379 do_spec_1 (" ", 0, NULL);
04380 }
04381 }
04382 }
04383 free (buffer);
04384 }
04385 break;
04386
04387 case 'e':
04388
04389
04390 {
04391 const char *q = p;
04392 char *buf;
04393 while (*p != 0 && *p != '\n')
04394 p++;
04395 buf = (char *) alloca (p - q + 1);
04396 strncpy (buf, q, p - q);
04397 buf[p - q] = 0;
04398 error ("%s", buf);
04399 return -1;
04400 }
04401 break;
04402 case 'n':
04403
04404 {
04405 const char *q = p;
04406 char *buf;
04407 while (*p != 0 && *p != '\n')
04408 p++;
04409 buf = (char *) alloca (p - q + 1);
04410 strncpy (buf, q, p - q);
04411 buf[p - q] = 0;
04412 notice ("%s\n", buf);
04413 if (*p)
04414 p++;
04415 }
04416 break;
04417
04418 case 'j':
04419 {
04420 struct stat st;
04421
04422
04423
04424
04425
04426
04427 if ((!save_temps_flag)
04428 && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
04429 && (access (HOST_BIT_BUCKET, W_OK) == 0))
04430 {
04431 obstack_grow (&obstack, HOST_BIT_BUCKET,
04432 strlen (HOST_BIT_BUCKET));
04433 delete_this_arg = 0;
04434 arg_going = 1;
04435 break;
04436 }
04437 }
04438 case 'g':
04439 case 'u':
04440 case 'U':
04441 {
04442 struct temp_name *t;
04443 int suffix_length;
04444 const char *suffix = p;
04445 char *saved_suffix = NULL;
04446
04447 while (*p == '.' || ISALPHA ((unsigned char) *p))
04448 p++;
04449 suffix_length = p - suffix;
04450 if (p[0] == '%' && p[1] == 'O')
04451 {
04452 p += 2;
04453
04454 if (*p == '.' || ISALPHA ((unsigned char) *p))
04455 abort ();
04456 if (suffix_length == 0)
04457 suffix = TARGET_OBJECT_SUFFIX;
04458 else
04459 {
04460 saved_suffix
04461 = (char *) xmalloc (suffix_length
04462 + strlen (TARGET_OBJECT_SUFFIX));
04463 strncpy (saved_suffix, suffix, suffix_length);
04464 strcpy (saved_suffix + suffix_length,
04465 TARGET_OBJECT_SUFFIX);
04466 }
04467 suffix_length += strlen (TARGET_OBJECT_SUFFIX);
04468 }
04469
04470
04471
04472
04473
04474
04475
04476
04477
04478 if (save_temps_flag)
04479 {
04480 temp_filename_length = basename_length + suffix_length;
04481 temp_filename = alloca (temp_filename_length + 1);
04482 strncpy ((char *) temp_filename, input_basename, basename_length);
04483 strncpy ((char *) temp_filename + basename_length, suffix,
04484 suffix_length);
04485 *((char *) temp_filename + temp_filename_length) = '\0';
04486 if (strcmp (temp_filename, input_filename) != 0)
04487 {
04488 struct stat st_temp;
04489
04490
04491 if (input_stat_set == 0)
04492 {
04493 input_stat_set = stat (input_filename, &input_stat);
04494 if (input_stat_set >= 0)
04495 input_stat_set = 1;
04496 }
04497
04498
04499
04500
04501
04502
04503 if (input_stat_set != 1
04504 || stat (temp_filename, &st_temp) < 0
04505 || input_stat.st_dev != st_temp.st_dev
04506 || input_stat.st_ino != st_temp.st_ino)
04507 {
04508 temp_filename = save_string (temp_filename,
04509 temp_filename_length + 1);
04510 obstack_grow (&obstack, temp_filename,
04511 temp_filename_length);
04512 arg_going = 1;
04513 delete_this_arg = 0;
04514 break;
04515 }
04516 }
04517 }
04518
04519
04520
04521 for (t = temp_names; t; t = t->next)
04522 if (t->length == suffix_length
04523 && strncmp (t->suffix, suffix, suffix_length) == 0
04524 && t->unique == (c != 'g'))
04525 break;
04526
04527
04528
04529 if (t == 0 || c == 'u' || c == 'j')
04530 {
04531 if (t == 0)
04532 {
04533 t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
04534 t->next = temp_names;
04535 temp_names = t;
04536 }
04537 t->length = suffix_length;
04538 if (saved_suffix)
04539 {
04540 t->suffix = saved_suffix;
04541 saved_suffix = NULL;
04542 }
04543 else
04544 t->suffix = save_string (suffix, suffix_length);
04545 t->unique = (c != 'g');
04546 temp_filename = make_temp_file (t->suffix);
04547 temp_filename_length = strlen (temp_filename);
04548 t->filename = temp_filename;
04549 t->filename_length = temp_filename_length;
04550 }
04551
04552 if (saved_suffix)
04553 free (saved_suffix);
04554
04555 obstack_grow (&obstack, t->filename, t->filename_length);
04556 delete_this_arg = 1;
04557 }
04558 arg_going = 1;
04559 break;
04560
04561 case 'i':
04562 obstack_grow (&obstack, input_filename, input_filename_length);
04563 arg_going = 1;
04564 break;
04565
04566 case 'I':
04567 {
04568 struct prefix_list *pl = include_prefixes.plist;
04569
04570 if (gcc_exec_prefix)
04571 {
04572 do_spec_1 ("-iprefix", 1, NULL);
04573
04574 do_spec_1 (" ", 0, NULL);
04575 do_spec_1 (gcc_exec_prefix, 1, NULL);
04576 do_spec_1 (" ", 0, NULL);
04577 }
04578
04579 for (; pl; pl = pl->next)
04580 {
04581 do_spec_1 ("-isystem", 1, NULL);
04582
04583 do_spec_1 (" ", 0, NULL);
04584 do_spec_1 (pl->prefix, 1, NULL);
04585 do_spec_1 (" ", 0, NULL);
04586 }
04587 }
04588 break;
04589
04590 case 'o':
04591 {
04592 int max = n_infiles;
04593 max += lang_specific_extra_outfiles;
04594
04595 for (i = 0; i < max; i++)
04596 if (outfiles[i])
04597 store_arg (outfiles[i], 0, 0);
04598 break;
04599 }
04600
04601 case 'O':
04602 obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
04603 arg_going = 1;
04604 break;
04605
04606 case 's':
04607 this_is_library_file = 1;
04608 break;
04609
04610 case 'w':
04611 this_is_output_file = 1;
04612 break;
04613
04614 case 'W':
04615 {
04616 int cur_index = argbuf_index;
04617
04618 if (*p != '{')
04619 abort ();
04620 p = handle_braces (p + 1);
04621 if (p == 0)
04622 return -1;
04623
04624
04625 if (argbuf_index != cur_index)
04626 record_temp_file (argbuf[argbuf_index - 1], 0, 1);
04627 break;
04628 }
04629
04630
04631 case 'x':
04632 {
04633 const char *p1 = p;
04634 char *string;
04635
04636
04637 if (*p != '{')
04638 abort ();
04639 while (*p++ != '}')
04640 ;
04641 string = save_string (p1 + 1, p - p1 - 2);
04642
04643
04644 for (i = 0; i < n_linker_options; i++)
04645 if (! strcmp (string, linker_options[i]))
04646 {
04647 free (string);
04648 return 0;
04649 }
04650
04651
04652 add_linker_option (string, strlen (string));
04653 }
04654 break;
04655
04656
04657 case 'X':
04658 for (i = 0; i < n_linker_options; i++)
04659 {
04660 do_spec_1 (linker_options[i], 1, NULL);
04661
04662 do_spec_1 (" ", 0, NULL);
04663 }
04664 break;
04665
04666
04667 case 'Y':
04668 for (i = 0; i < n_assembler_options; i++)
04669 {
04670 do_spec_1 (assembler_options[i], 1, NULL);
04671
04672 do_spec_1 (" ", 0, NULL);
04673 }
04674 break;
04675
04676
04677 case 'Z':
04678 for (i = 0; i < n_preprocessor_options; i++)
04679 {
04680 do_spec_1 (preprocessor_options[i], 1, NULL);
04681
04682 do_spec_1 (" ", 0, NULL);
04683 }
04684 break;
04685
04686
04687
04688
04689 case '1':
04690 value = do_spec_1 (cc1_spec, 0, NULL);
04691 if (value != 0)
04692 return value;
04693 break;
04694
04695 case '2':
04696 value = do_spec_1 (cc1plus_spec, 0, NULL);
04697 if (value != 0)
04698 return value;
04699 break;
04700
04701 case 'a':
04702 value = do_spec_1 (asm_spec, 0, NULL);
04703 if (value != 0)
04704 return value;
04705 break;
04706
04707 case 'A':
04708 value = do_spec_1 (asm_final_spec, 0, NULL);
04709 if (value != 0)
04710 return value;
04711 break;
04712
04713 case 'C':
04714 {
04715 const char *const spec
04716 = (input_file_compiler->cpp_spec
04717 ? input_file_compiler->cpp_spec
04718 : cpp_spec);
04719 value = do_spec_1 (spec, 0, NULL);
04720 if (value != 0)
04721 return value;
04722 }
04723 break;
04724
04725 case 'E':
04726 value = do_spec_1 (endfile_spec, 0, NULL);
04727 if (value != 0)
04728 return value;
04729 break;
04730
04731 case 'l':
04732 value = do_spec_1 (link_spec, 0, NULL);
04733 if (value != 0)
04734 return value;
04735 break;
04736
04737 case 'L':
04738 value = do_spec_1 (lib_spec, 0, NULL);
04739 if (value != 0)
04740 return value;
04741 break;
04742
04743 case 'G':
04744 value = do_spec_1 (libgcc_spec, 0, NULL);
04745 if (value != 0)
04746 return value;
04747 break;
04748
04749 case 'M':
04750 if (multilib_dir && strcmp (multilib_dir, ".") != 0)
04751 {
04752 char *p;
04753 const char *q;
04754 size_t len;
04755
04756 len = strlen (multilib_dir);
04757 obstack_blank (&obstack, len + 1);
04758 p = obstack_next_free (&obstack) - (len + 1);
04759
04760 *p++ = '_';
04761 for (q = multilib_dir; *q ; ++q, ++p)
04762 *p = (IS_DIR_SEPARATOR (*q) ? '_' : *q);
04763 }
04764 break;
04765
04766 case 'p':
04767 {
04768 char *x = (char *) alloca (strlen (cpp_predefines) + 1);
04769 char *buf = x;
04770 const char *y;
04771
04772
04773 y = cpp_predefines;
04774 while (*y != 0)
04775 {
04776 if (! strncmp (y, "-D", 2))
04777
04778 while (*y && *y != ' ' && *y != '\t')
04779 *x++ = *y++;
04780 else if (*y == ' ' || *y == '\t')
04781
04782 *x++ = *y++;
04783
04784 else
04785 y++;
04786 }
04787
04788 *x = 0;
04789
04790 value = do_spec_1 (buf, 0, NULL);
04791 if (value != 0)
04792 return value;
04793 }
04794 break;
04795
04796 case 'P':
04797 {
04798 char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
04799 char *buf = x;
04800 const char *y;
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810 y = cpp_predefines;
04811 while (*y != 0)
04812 {
04813 if (! strncmp (y, "-D", 2))
04814 {
04815 int flag = 0;
04816
04817 *x++ = *y++;
04818 *x++ = *y++;
04819
04820 if (*y != '_'
04821 || (*(y + 1) != '_'
04822 && ! ISUPPER ((unsigned char) *(y + 1))))
04823 {
04824
04825 if (*y != '_')
04826 *x++ = '_';
04827 *x++ = '_';
04828
04829 flag = 1;
04830 }
04831
04832
04833 while (*y && *y != '=' && *y != ' ' && *y != '\t')
04834 *x++ = *y++;
04835
04836 if (flag)
04837 {
04838 if (x[-1] != '_')
04839 {
04840 if (x[-2] != '_')
04841 *x++ = '_';
04842 *x++ = '_';
04843 }
04844 }
04845
04846
04847 while (*y && *y != ' ' && *y != '\t')
04848 *x++ = *y++;
04849 }
04850 else if (*y == ' ' || *y == '\t')
04851
04852 *x++ = *y++;
04853
04854 else
04855 y++;
04856 }
04857 *x++ = ' ';
04858
04859
04860
04861 y = cpp_predefines;
04862 while (*y != 0)
04863 {
04864 if (! strncmp (y, "-D", 2))
04865 {
04866 y += 2;
04867
04868 if (*y != '_'
04869 || (*(y + 1) != '_'
04870 && ! ISUPPER ((unsigned char) *(y + 1))))
04871 {
04872
04873 *x++ = '-';
04874 *x++ = 'D';
04875 if (*y != '_')
04876 *x++ = '_';
04877 *x++ = '_';
04878
04879
04880 while (*y && *y != '=' && *y != ' ' && *y != '\t')
04881 *x++ = *y++;
04882
04883
04884 while (*y && *y != ' ' && *y != '\t')
04885 *x++ = *y++;
04886 }
04887 else
04888 {
04889
04890 while (*y && *y != ' ' && *y != '\t')
04891 y++;
04892 }
04893 }
04894 else if (*y == ' ' || *y == '\t')
04895
04896 *x++ = *y++;
04897
04898 else
04899 y++;
04900 }
04901 *x++ = ' ';
04902
04903
04904 y = cpp_predefines;
04905 while (*y != 0)
04906 {
04907 if (! strncmp (y, "-A", 2))
04908
04909 while (*y && *y != ' ' && *y != '\t')
04910 *x++ = *y++;
04911 else if (*y == ' ' || *y == '\t')
04912
04913 *x++ = *y++;
04914
04915 else
04916 y++;
04917 }
04918
04919 *x = 0;
04920
04921 value = do_spec_1 (buf, 0, NULL);
04922 if (value != 0)
04923 return value;
04924 }
04925 break;
04926
04927 case 'S':
04928 value = do_spec_1 (startfile_spec, 0, NULL);
04929 if (value != 0)
04930 return value;
04931 break;
04932
04933
04934
04935 case '{':
04936 p = handle_braces (p);
04937 if (p == 0)
04938 return -1;
04939 break;
04940
04941 case ':':
04942 p = handle_spec_function (p);
04943 if (p == 0)
04944 return -1;
04945 break;
04946
04947 case '%':
04948 obstack_1grow (&obstack, '%');
04949 break;
04950
04951 case '.':
04952 {
04953 unsigned len = 0;
04954
04955 while (p[len] && p[len] != ' ' && p[len] != '%')
04956 len++;
04957 suffix_subst = save_string (p - 1, len + 1);
04958 p += len;
04959 }
04960 break;
04961
04962 case '*':
04963 if (soft_matched_part)
04964 {
04965 do_spec_1 (soft_matched_part, 1, NULL);
04966 do_spec_1 (" ", 0, NULL);
04967 }
04968 else
04969
04970
04971
04972 error ("spec failure: '%%*' has not been initialized by pattern match");
04973 break;
04974
04975
04976
04977
04978
04979
04980 case '[':
04981 error ("warning: use of obsolete %%[ operator in specs");
04982 case '(':
04983 {
04984 const char *name = p;
04985 struct spec_list *sl;
04986 int len;
04987
04988
04989
04990 while (*p && *p != ')' && *p != ']')
04991 p++;
04992
04993
04994 for (len = p - name, sl = specs; sl; sl = sl->next)
04995 if (sl->name_len == len && !strncmp (sl->name, name, len))
04996 {
04997 name = *(sl->ptr_spec);
04998 #ifdef DEBUG_SPECS
04999 notice ("Processing spec %c%s%c, which is '%s'\n",
05000 c, sl->name, (c == '(') ? ')' : ']', name);
05001 #endif
05002 break;
05003 }
05004
05005 if (sl)
05006 {
05007 if (c == '(')
05008 {
05009 value = do_spec_1 (name, 0, NULL);
05010 if (value != 0)
05011 return value;
05012 }
05013 else
05014 {
05015 char *x = (char *) alloca (strlen (name) * 2 + 1);
05016 char *buf = x;
05017 const char *y = name;
05018 int flag = 0;
05019
05020
05021
05022 while (1)
05023 {
05024 if (! strncmp (y, "-D", 2))
05025 {
05026 *x++ = '-';
05027 *x++ = 'D';
05028 *x++ = '_';
05029 *x++ = '_';
05030 y += 2;
05031 flag = 1;
05032 continue;
05033 }
05034 else if (flag
05035 && (*y == ' ' || *y == '\t' || *y == '='
05036 || *y == '}' || *y == 0))
05037 {
05038 *x++ = '_';
05039 *x++ = '_';
05040 flag = 0;
05041 }
05042 if (*y == 0)
05043 break;
05044 else
05045 *x++ = *y++;
05046 }
05047 *x = 0;
05048
05049 value = do_spec_1 (buf, 0, NULL);
05050 if (value != 0)
05051 return value;
05052 }
05053 }
05054
05055
05056 if (*p)
05057 p++;
05058 }
05059 break;
05060
05061 case 'v':
05062 {
05063 int c1 = *p++;
05064 const char *v = compiler_version;
05065 const char *q;
05066 static const char zeroc = '0';
05067
05068
05069
05070
05071
05072 while (! ISDIGIT (*v))
05073 v++;
05074 if (v > compiler_version && v[-1] != '-')
05075 abort ();
05076
05077
05078 if (c1 >= '2')
05079 {
05080
05081 while (ISDIGIT (*v))
05082 v++;
05083 if (*v != '.')
05084 abort ();
05085 v++;
05086 }
05087
05088
05089
05090 if (c1 == '3')
05091 {
05092
05093 while (ISDIGIT (*v))
05094 v++;
05095 if ((*v != 0) && (*v != ' ') && (*v != '.') && (*v != '-'))
05096 abort ();
05097 if (*v != 0)
05098 v++;
05099 }
05100
05101
05102 q = v;
05103 while (ISDIGIT (*q))
05104 q++;
05105 if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
05106 abort ();
05107
05108 if (q > v)
05109
05110 obstack_grow (&obstack, v, q - v);
05111 else
05112
05113 obstack_grow (&obstack, &zeroc, 1);
05114 arg_going = 1;
05115 }
05116 break;
05117
05118 case '|':
05119 if (input_from_pipe)
05120 do_spec_1 ("-", 0, NULL);
05121 break;
05122
05123 default:
05124 error ("spec failure: unrecognized spec option '%c'", c);
05125 break;
05126 }
05127 break;
05128
05129 case '\\':
05130
05131 c = *p++;
05132
05133
05134 default:
05135
05136 obstack_1grow (&obstack, c);
05137 arg_going = 1;
05138 }
05139
05140
05141
05142 if (processing_spec_function && arg_going)
05143 {
05144 obstack_1grow (&obstack, 0);
05145 string = obstack_finish (&obstack);
05146 if (this_is_library_file)
05147 string = find_file (string);
05148 store_arg (string, delete_this_arg, this_is_output_file);
05149 if (this_is_output_file)
05150 outfiles[input_file_number] = string;
05151 arg_going = 0;
05152 }
05153
05154 return 0;
05155 }
05156
05157
05158
05159 static const struct spec_function *
05160 lookup_spec_function (name)
05161 const char *name;
05162 {
05163 static const struct spec_function * const spec_function_tables[] =
05164 {
05165 static_spec_functions,
05166 lang_specific_spec_functions,
05167 };
05168 const struct spec_function *sf;
05169 unsigned int i;
05170
05171 for (i = 0; i < ARRAY_SIZE (spec_function_tables); i++)
05172 {
05173 for (sf = spec_function_tables[i]; sf->name != NULL; sf++)
05174 if (strcmp (sf->name, name) == 0)
05175 return sf;
05176 }
05177
05178 return NULL;
05179 }
05180
05181
05182
05183 static const char *
05184 eval_spec_function (func, args)
05185 const char *func, *args;
05186 {
05187 const struct spec_function *sf;
05188 const char *funcval;
05189
05190
05191 int save_argbuf_index;
05192 int save_argbuf_length;
05193 const char **save_argbuf;
05194
05195 int save_arg_going;
05196 int save_delete_this_arg;
05197 int save_this_is_output_file;
05198 int save_this_is_library_file;
05199 int save_input_from_pipe;
05200 const char *save_suffix_subst;
05201
05202
05203 sf = lookup_spec_function (func);
05204 if (sf == NULL)
05205 fatal ("unknown spec function `%s'", func);
05206
05207
05208 save_argbuf_index = argbuf_index;
05209 save_argbuf_length = argbuf_length;
05210 save_argbuf = argbuf;
05211
05212 save_arg_going = arg_going;
05213 save_delete_this_arg = delete_this_arg;
05214 save_this_is_output_file = this_is_output_file;
05215 save_this_is_library_file = this_is_library_file;
05216 save_input_from_pipe = input_from_pipe;
05217 save_suffix_subst = suffix_subst;
05218
05219
05220
05221
05222 alloc_args ();
05223 if (do_spec_2 (args) < 0)
05224 fatal ("error in args to spec function `%s'", func);
05225
05226
05227
05228
05229 funcval = (*sf->func) (argbuf_index, argbuf);
05230
05231
05232 argbuf_index = save_argbuf_index;
05233 argbuf_length = save_argbuf_length;
05234 free (argbuf);
05235 argbuf = save_argbuf;
05236
05237 arg_going = save_arg_going;
05238 delete_this_arg = save_delete_this_arg;
05239 this_is_output_file = save_this_is_output_file;
05240 this_is_library_file = save_this_is_library_file;
05241 input_from_pipe = save_input_from_pipe;
05242 suffix_subst = save_suffix_subst;
05243
05244 return funcval;
05245 }
05246
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256 static const char *
05257 handle_spec_function (p)
05258 const char *p;
05259 {
05260 char *func, *args;
05261 const char *endp, *funcval;
05262 int count;
05263
05264 processing_spec_function++;
05265
05266
05267 for (endp = p; *endp != '\0'; endp++)
05268 {
05269 if (*endp == '(')
05270 break;
05271
05272 if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
05273 fatal ("malformed spec function name");
05274 }
05275 if (*endp != '(')
05276 fatal ("no arguments for spec function");
05277 func = save_string (p, endp - p);
05278 p = ++endp;
05279
05280
05281 for (count = 0; *endp != '\0'; endp++)
05282 {
05283
05284 if (*endp == ')')
05285 {
05286 if (count == 0)
05287 break;
05288 count--;
05289 }
05290 else if (*endp == '(')
05291 count++;
05292 }
05293
05294 if (*endp != ')')
05295 fatal ("malformed spec function arguments");
05296 args = save_string (p, endp - p);
05297 p = ++endp;
05298
05299
05300
05301 funcval = eval_spec_function (func, args);
05302 if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
05303 p = NULL;
05304
05305 free (func);
05306 free (args);
05307
05308 processing_spec_function--;
05309
05310 return p;
05311 }
05312
05313
05314
05315 static const char *
05316 handle_braces (p)
05317 const char *p;
05318 {
05319 const char *filter, *body = NULL, *endbody = NULL;
05320 int pipe_p = 0;
05321 int true_once = 0;
05322 int negate;
05323 int suffix;
05324 int include_blanks = 1;
05325 int elide_switch = 0;
05326 int ordered = 0;
05327
05328 if (*p == '^')
05329 {
05330
05331 include_blanks = 0;
05332 ++p;
05333 }
05334
05335 if (*p == '|')
05336 {
05337
05338
05339
05340 pipe_p = 1;
05341 ++p;
05342 }
05343
05344 if (*p == '<')
05345 {
05346
05347
05348 elide_switch = 1;
05349 ++p;
05350 }
05351
05352 next_member:
05353 negate = suffix = 0;
05354
05355 if (*p == '!')
05356
05357
05358 negate = 1, ++p;
05359
05360 if (*p == '.')
05361
05362 {
05363 if (pipe_p)
05364 abort ();
05365
05366 suffix = 1;
05367 ++p;
05368 }
05369
05370 if (elide_switch && (negate || pipe_p || suffix))
05371 {
05372
05373
05374 abort ();
05375 }
05376
05377 next_ampersand:
05378 filter = p;
05379 while (*p != ':' && *p != '}' && *p != '|' && *p != '&')
05380 p++;
05381
05382 if (*p == '|' && (pipe_p || ordered))
05383 abort ();
05384
05385 if (!body)
05386 {
05387 if (*p != '}' && *p != '&')
05388 {
05389 int count = 1;
05390 const char *q = p;
05391
05392 while (*q++ != ':')
05393 continue;
05394 body = q;
05395
05396 while (count > 0)
05397 {
05398 if (*q == '{')
05399 count++;
05400 else if (*q == '}')
05401 count--;
05402 else if (*q == 0)
05403 fatal ("mismatched braces in specs");
05404 q++;
05405 }
05406 endbody = q;
05407 }
05408 else
05409 body = p, endbody = p + 1;
05410 }
05411
05412 if (suffix)
05413 {
05414 int found = (input_suffix != 0
05415 && (long) strlen (input_suffix) == (long) (p - filter)
05416 && strncmp (input_suffix, filter, p - filter) == 0);
05417
05418 if (body[0] == '}')
05419 abort ();
05420
05421 if (negate != found
05422 && do_spec_1 (save_string (body, endbody-body-1), 0, NULL) < 0)
05423 return 0;
05424 }
05425 else if (p[-1] == '*' && (p[0] == '}' || p[0] == '&'))
05426 {
05427
05428 int i;
05429
05430 for (i = 0; i < n_switches; i++)
05431 if (!strncmp (switches[i].part1, filter, p - 1 - filter)
05432 && check_live_switch (i, p - 1 - filter))
05433 {
05434 if (elide_switch)
05435 {
05436 switches[i].live_cond = SWITCH_IGNORE;
05437 switches[i].validated = 1;
05438 }
05439 else
05440 ordered = 1, switches[i].ordering = 1;
05441 }
05442 }
05443 else
05444 {
05445
05446 int i;
05447 int present = 0;
05448
05449
05450
05451 if (p[-1] == '*' && !negate)
05452 {
05453 int substitution;
05454 const char *r = body;
05455
05456
05457 substitution = 0;
05458 while (r < endbody)
05459 {
05460 if (*r == '%' && r[1] == '*')
05461 substitution = 1;
05462 r++;
05463 }
05464
05465 if (substitution)
05466 {
05467
05468
05469
05470
05471 unsigned hard_match_len = p - filter - 1;
05472 char *string = save_string (body, endbody - body - 1);
05473
05474 for (i = 0; i < n_switches; i++)
05475 if (!strncmp (switches[i].part1, filter, hard_match_len)
05476 && check_live_switch (i, -1))
05477 {
05478 do_spec_1 (string, 0, &switches[i].part1[hard_match_len]);
05479
05480 give_switch (i, 1, 1);
05481 suffix_subst = NULL;
05482 }
05483
05484
05485 if (*p++ == '|')
05486 goto next_member;
05487 return endbody;
05488 }
05489 }
05490
05491
05492
05493 if (p[-1] == '*')
05494 {
05495 for (i = 0; i < n_switches; i++)
05496 {
05497 unsigned hard_match_len = p - filter - 1;
05498
05499 if (!strncmp (switches[i].part1, filter, hard_match_len)
05500 && check_live_switch (i, hard_match_len))
05501 {
05502 present = 1;
05503 break;
05504 }
05505 }
05506 }
05507
05508 else
05509 {
05510 for (i = 0; i < n_switches; i++)
05511 {
05512 if (!strncmp (switches[i].part1, filter, p - filter)
05513 && switches[i].part1[p - filter] == 0
05514 && check_live_switch (i, -1))
05515 {
05516 present = 1;
05517 break;
05518 }
05519 }
05520 }
05521
05522
05523
05524
05525 if (present != negate)
05526 {
05527 if (elide_switch)
05528 {
05529 switches[i].live_cond = SWITCH_IGNORE;
05530 switches[i].validated = 1;
05531 }
05532 else if (ordered || *p == '&')
05533 ordered = 1, switches[i].ordering = 1;
05534 else if (*p == '}')
05535 give_switch (i, 0, include_blanks);
05536 else
05537
05538 true_once = 1;
05539 }
05540 else if (pipe_p)
05541 {
05542
05543
05544 do_spec_1 ("-", 0, NULL);
05545 return endbody;
05546 }
05547 }
05548
05549
05550 if (*p++ == '|')
05551 goto next_member;
05552
05553 if (p[-1] == '&')
05554 {
05555 body = 0;
05556 goto next_ampersand;
05557 }
05558
05559 if (ordered)
05560 {
05561 int i;
05562
05563
05564 for (i = 0; i < n_switches; i++)
05565 if (switches[i].ordering == 1)
05566 {
05567 switches[i].ordering = 0;
05568 give_switch (i, 0, include_blanks);
05569 }
05570 }
05571
05572 else if (true_once)
05573 {
05574 if (do_spec_1 (save_string (body, endbody - body - 1),
05575 0, NULL) < 0)
05576 return 0;
05577 }
05578
05579 return endbody;
05580 }
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590 static int
05591 check_live_switch (switchnum, prefix_length)
05592 int switchnum;
05593 int prefix_length;
05594 {
05595 const char *name = switches[switchnum].part1;
05596 int i;
05597
05598
05599
05600
05601 if (prefix_length >= 0 && prefix_length <= 1)
05602 return 1;
05603
05604
05605
05606 if (switches[switchnum].live_cond != 0)
05607 return switches[switchnum].live_cond > 0;
05608
05609
05610 switch (*name)
05611 {
05612 case 'O':
05613 for (i = switchnum + 1; i < n_switches; i++)
05614 if (switches[i].part1[0] == 'O')
05615 {
05616 switches[switchnum].validated = 1;
05617 switches[switchnum].live_cond = SWITCH_FALSE;
05618 return 0;
05619 }
05620 break;
05621
05622 case 'W': case 'f': case 'm':
05623 if (! strncmp (name + 1, "no-", 3))
05624 {
05625
05626 for (i = switchnum + 1; i < n_switches; i++)
05627 if (switches[i].part1[0] == name[0]
05628 && ! strcmp (&switches[i].part1[1], &name[4]))
05629 {
05630 switches[switchnum].validated = 1;
05631 switches[switchnum].live_cond = SWITCH_FALSE;
05632 return 0;
05633 }
05634 }
05635 else
05636 {
05637
05638 for (i = switchnum + 1; i < n_switches; i++)
05639 if (switches[i].part1[0] == name[0]
05640 && switches[i].part1[1] == 'n'
05641 && switches[i].part1[2] == 'o'
05642 && switches[i].part1[3] == '-'
05643 && !strcmp (&switches[i].part1[4], &name[1]))
05644 {
05645 switches[switchnum].validated = 1;
05646 switches[switchnum].live_cond = SWITCH_FALSE;
05647 return 0;
05648 }
05649 }
05650 break;
05651 }
05652
05653
05654 switches[switchnum].live_cond = SWITCH_LIVE;
05655 return 1;
05656 }
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669 static void
05670 give_switch (switchnum, omit_first_word, include_blanks)
05671 int switchnum;
05672 int omit_first_word;
05673 int include_blanks;
05674 {
05675 if (switches[switchnum].live_cond == SWITCH_IGNORE)
05676 return;
05677
05678 if (!omit_first_word)
05679 {
05680 do_spec_1 ("-", 0, NULL);
05681 do_spec_1 (switches[switchnum].part1, 1, NULL);
05682 }
05683
05684 if (switches[switchnum].args != 0)
05685 {
05686 const char **p;
05687 for (p = switches[switchnum].args; *p; p++)
05688 {
05689 const char *arg = *p;
05690
05691 if (include_blanks)
05692 do_spec_1 (" ", 0, NULL);
05693 if (suffix_subst)
05694 {
05695 unsigned length = strlen (arg);
05696 int dot = 0;
05697
05698 while (length-- && !IS_DIR_SEPARATOR (arg[length]))
05699 if (arg[length] == '.')
05700 {
05701 ((char *)arg)[length] = 0;
05702 dot = 1;
05703 break;
05704 }
05705 do_spec_1 (arg, 1, NULL);
05706 if (dot)
05707 ((char *)arg)[length] = '.';
05708 do_spec_1 (suffix_subst, 1, NULL);
05709 }
05710 else
05711 do_spec_1 (arg, 1, NULL);
05712 }
05713 }
05714
05715 do_spec_1 (" ", 0, NULL);
05716 switches[switchnum].validated = 1;
05717 }
05718
05719
05720
05721
05722
05723 static const char *
05724 find_file (name)
05725 const char *name;
05726 {
05727 char *newname;
05728
05729
05730 if (multilib_os_dir != NULL)
05731 {
05732 newname = find_a_file (&startfile_prefixes, name, R_OK, 1);
05733
05734
05735
05736 if (newname != NULL)
05737 return newname;
05738 }
05739
05740 newname = find_a_file (&startfile_prefixes, name, R_OK, 0);
05741 return newname ? newname : name;
05742 }
05743
05744
05745
05746
05747
05748
05749 static int
05750 is_directory (path1, path2, linker)
05751 const char *path1;
05752 const char *path2;
05753 int linker;
05754 {
05755 int len1 = strlen (path1);
05756 int len2 = strlen (path2);
05757 char *path = (char *) alloca (3 + len1 + len2);
05758 char *cp;
05759 struct stat st;
05760
05761 #ifndef SMALL_ARG_MAX
05762 if (! linker)
05763 return 1;
05764 #endif
05765
05766
05767
05768
05769 memcpy (path, path1, len1);
05770 memcpy (path + len1, path2, len2);
05771 cp = path + len1 + len2;
05772 if (!IS_DIR_SEPARATOR (cp[-1]))
05773 *cp++ = DIR_SEPARATOR;
05774 *cp++ = '.';
05775 *cp = '\0';
05776
05777
05778 if (linker
05779 && ((cp - path == 6
05780 && strcmp (path, concat (dir_separator_str, "lib",
05781 dir_separator_str, ".", NULL)) == 0)
05782 || (cp - path == 10
05783 && strcmp (path, concat (dir_separator_str, "usr",
05784 dir_separator_str, "lib",
05785 dir_separator_str, ".", NULL)) == 0)))
05786 return 0;
05787
05788 return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
05789 }
05790
05791
05792
05793
05794 void
05795 set_input (filename)
05796 const char *filename;
05797 {
05798 const char *p;
05799
05800 input_filename = filename;
05801 input_filename_length = strlen (input_filename);
05802
05803 input_basename = input_filename;
05804 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
05805
05806 if (input_basename[1] == ':')
05807 input_basename += 2;
05808 #endif
05809 for (p = input_basename; *p; p++)
05810 if (IS_DIR_SEPARATOR (*p))
05811 input_basename = p + 1;
05812
05813
05814
05815 basename_length = strlen (input_basename);
05816 suffixed_basename_length = basename_length;
05817 p = input_basename + basename_length;
05818 while (p != input_basename && *p != '.')
05819 --p;
05820 if (*p == '.' && p != input_basename)
05821 {
05822 basename_length = p - input_basename;
05823 input_suffix = p + 1;
05824 }
05825 else
05826 input_suffix = "";
05827
05828
05829
05830
05831 input_stat_set = 0;
05832 }
05833
05834
05835
05836 static void
05837 fatal_error (signum)
05838 int signum;
05839 {
05840 signal (signum, SIG_DFL);
05841 delete_failure_queue ();
05842 delete_temp_files ();
05843
05844
05845 kill (getpid (), signum);
05846 }
05847
05848 extern int main PARAMS ((int, const char *const *));
05849
05850 int
05851 main (argc, argv)
05852 int argc;
05853 const char *const *argv;
05854 {
05855 size_t i;
05856 int value;
05857 int linker_was_run = 0;
05858 char *explicit_link_files;
05859 char *specs_file;
05860 const char *p;
05861 struct user_specs *uptr;
05862
05863 p = argv[0] + strlen (argv[0]);
05864 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
05865 --p;
05866 programname = p;
05867
05868 xmalloc_set_program_name (programname);
05869
05870 #ifdef GCC_DRIVER_HOST_INITIALIZATION
05871
05872 GCC_DRIVER_HOST_INITIALIZATION;
05873 #endif
05874
05875 gcc_init_libintl ();
05876
05877 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
05878 signal (SIGINT, fatal_error);
05879 #ifdef SIGHUP
05880 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
05881 signal (SIGHUP, fatal_error);
05882 #endif
05883 if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
05884 signal (SIGTERM, fatal_error);
05885 #ifdef SIGPIPE
05886 if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
05887 signal (SIGPIPE, fatal_error);
05888 #endif
05889 #ifdef SIGCHLD
05890
05891
05892 signal (SIGCHLD, SIG_DFL);
05893 #endif
05894
05895
05896 alloc_args ();
05897
05898 obstack_init (&obstack);
05899
05900
05901
05902 {
05903 const char *const *q = multilib_raw;
05904 int need_space;
05905
05906 obstack_init (&multilib_obstack);
05907 while ((p = *q++) != (char *) 0)
05908 obstack_grow (&multilib_obstack, p, strlen (p));
05909
05910 obstack_1grow (&multilib_obstack, 0);
05911 multilib_select = obstack_finish (&multilib_obstack);
05912
05913 q = multilib_matches_raw;
05914 while ((p = *q++) != (char *) 0)
05915 obstack_grow (&multilib_obstack, p, strlen (p));
05916
05917 obstack_1grow (&multilib_obstack, 0);
05918 multilib_matches = obstack_finish (&multilib_obstack);
05919
05920 q = multilib_exclusions_raw;
05921 while ((p = *q++) != (char *) 0)
05922 obstack_grow (&multilib_obstack, p, strlen (p));
05923
05924 obstack_1grow (&multilib_obstack, 0);
05925 multilib_exclusions = obstack_finish (&multilib_obstack);
05926
05927 need_space = FALSE;
05928 for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
05929 {
05930 if (need_space)
05931 obstack_1grow (&multilib_obstack, ' ');
05932 obstack_grow (&multilib_obstack,
05933 multilib_defaults_raw[i],
05934 strlen (multilib_defaults_raw[i]));
05935 need_space = TRUE;
05936 }
05937
05938 obstack_1grow (&multilib_obstack, 0);
05939 multilib_defaults = obstack_finish (&multilib_obstack);
05940 }
05941
05942
05943
05944
05945 obstack_init (&collect_obstack);
05946 obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
05947 obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
05948 putenv (obstack_finish (&collect_obstack));
05949
05950 #ifdef INIT_ENVIRONMENT
05951
05952 putenv (INIT_ENVIRONMENT);
05953 #endif
05954
05955
05956
05957
05958
05959 process_command (argc, argv);
05960
05961
05962
05963
05964 for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
05965 do_self_spec (driver_self_specs[i]);
05966
05967
05968
05969
05970 compilers = (struct compiler *) xmalloc (sizeof default_compilers);
05971 memcpy ((char *) compilers, (char *) default_compilers,
05972 sizeof default_compilers);
05973 n_compilers = n_default_compilers;
05974
05975
05976
05977 machine_suffix = concat (spec_machine, dir_separator_str,
05978 spec_version, dir_separator_str, NULL);
05979 just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
05980
05981 specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, 0);
05982
05983 if (specs_file != 0 && strcmp (specs_file, "specs"))
05984 read_specs (specs_file, TRUE);
05985 else
05986 init_spec ();
05987
05988
05989
05990 specs_file = (char *) alloca (strlen (standard_exec_prefix)
05991 + strlen (just_machine_suffix)
05992 + sizeof ("specs"));
05993
05994 strcpy (specs_file, standard_exec_prefix);
05995 strcat (specs_file, just_machine_suffix);
05996 strcat (specs_file, "specs");
05997 if (access (specs_file, R_OK) == 0)
05998 read_specs (specs_file, TRUE);
05999
06000
06001
06002
06003 if (*cross_compile == '0' && *startfile_prefix_spec == 0)
06004 {
06005 if (*md_exec_prefix)
06006 {
06007 add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
06008 PREFIX_PRIORITY_LAST, 0, NULL, 0);
06009 add_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
06010 PREFIX_PRIORITY_LAST, 0, NULL, 0);
06011 }
06012
06013 if (*md_startfile_prefix)
06014 add_prefix (&startfile_prefixes, md_startfile_prefix, "GCC",
06015 PREFIX_PRIORITY_LAST, 0, NULL, 1);
06016
06017 if (*md_startfile_prefix_1)
06018 add_prefix (&startfile_prefixes, md_startfile_prefix_1, "GCC",
06019 PREFIX_PRIORITY_LAST, 0, NULL, 1);
06020
06021
06022
06023
06024
06025 if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix))
06026 add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS",
06027 PREFIX_PRIORITY_LAST, 0, NULL, 1);
06028 else
06029 {
06030 if (gcc_exec_prefix)
06031 add_prefix (&startfile_prefixes,
06032 concat (gcc_exec_prefix, machine_suffix,
06033 standard_startfile_prefix, NULL),
06034 NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
06035 add_prefix (&startfile_prefixes,
06036 concat (standard_exec_prefix,
06037 machine_suffix,
06038 standard_startfile_prefix, NULL),
06039 NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
06040 }
06041
06042 add_prefix (&startfile_prefixes, standard_startfile_prefix_1,
06043 "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
06044 add_prefix (&startfile_prefixes, standard_startfile_prefix_2,
06045 "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
06046 #if 0
06047 add_prefix (&startfile_prefixes, "./", NULL,
06048 PREFIX_PRIORITY_LAST, 1, NULL, 0);
06049 #endif
06050 }
06051 else
06052 {
06053 if (!IS_ABSOLUTE_PATHNAME (standard_startfile_prefix)
06054 && gcc_exec_prefix)
06055 add_prefix (&startfile_prefixes,
06056 concat (gcc_exec_prefix, machine_suffix,
06057 standard_startfile_prefix, NULL),
06058 "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
06059 }
06060
06061 if (*startfile_prefix_spec != 0
06062 && do_spec_2 (startfile_prefix_spec) == 0
06063 && do_spec_1 (" ", 0, NULL) == 0)
06064 {
06065 int ndx;
06066 for (ndx = 0; ndx < argbuf_index; ndx++)
06067 add_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
06068 PREFIX_PRIORITY_LAST, 0, NULL, 1);
06069 }
06070
06071
06072
06073 for (uptr = user_specs_head; uptr; uptr = uptr->next)
06074 {
06075 char *filename = find_a_file (&startfile_prefixes, uptr->filename,
06076 R_OK, 0);
06077 read_specs (filename ? filename : uptr->filename, FALSE);
06078 }
06079
06080
06081 if (gcc_exec_prefix)
06082 gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
06083 spec_version, dir_separator_str, NULL);
06084
06085
06086
06087
06088 validate_all_switches ();
06089
06090
06091
06092 set_multilib_dir ();
06093
06094
06095
06096 for (i = 0; (int) i < n_switches; i++)
06097 if (! switches[i].validated)
06098 error ("unrecognized option `-%s'", switches[i].part1);
06099
06100
06101
06102 if (print_search_dirs)
06103 {
06104 printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
06105 printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
06106 printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
06107 return (0);
06108 }
06109
06110 if (print_file_name)
06111 {
06112 printf ("%s\n", find_file (print_file_name));
06113 return (0);
06114 }
06115
06116 if (print_prog_name)
06117 {
06118 char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
06119 printf ("%s\n", (newname ? newname : print_prog_name));
06120 return (0);
06121 }
06122
06123 if (print_multi_lib)
06124 {
06125 print_multilib_info ();
06126 return (0);
06127 }
06128
06129 if (print_multi_directory)
06130 {
06131 if (multilib_dir == NULL)
06132 printf (".\n");
06133 else
06134 printf ("%s\n", multilib_dir);
06135 return (0);
06136 }
06137
06138 if (print_multi_os_directory)
06139 {
06140 if (multilib_os_dir == NULL)
06141 printf (".\n");
06142 else
06143 printf ("%s\n", multilib_os_dir);
06144 return (0);
06145 }
06146
06147 if (target_help_flag)
06148 {
06149
06150
06151
06152
06153
06154
06155 }
06156
06157 if (print_help_list)
06158 {
06159 display_help ();
06160
06161 if (! verbose_flag)
06162 {
06163 printf (_("\nFor bug reporting instructions, please see:\n"));
06164 printf ("%s.\n", bug_report_url);
06165
06166 return (0);
06167 }
06168
06169
06170
06171
06172 }
06173
06174 if (verbose_flag)
06175 {
06176 int n;
06177 const char *thrmod;
06178
06179 notice ("Configured with: %s\n", configuration_arguments);
06180
06181 #ifdef THREAD_MODEL_SPEC
06182
06183
06184
06185 obstack_init (&obstack);
06186 do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
06187 obstack_1grow (&obstack, '\0');
06188 thrmod = obstack_finish (&obstack);
06189 #else
06190 thrmod = thread_model;
06191 #endif
06192
06193 notice ("Thread model: %s\n", thrmod);
06194
06195
06196
06197
06198 for (n = 0; version_string[n]; n++)
06199 if (version_string[n] == ' ')
06200 break;
06201
06202 if (! strncmp (version_string, compiler_version, n)
06203 && compiler_version[n] == 0)
06204 notice ("gcc version %s\n", version_string);
06205 else
06206 notice ("gcc driver version %s executing gcc version %s\n",
06207 version_string, compiler_version);
06208
06209 if (n_infiles == 0)
06210 return (0);
06211 }
06212
06213 if (n_infiles == added_libraries)
06214 fatal ("no input files");
06215
06216
06217
06218
06219 i = n_infiles;
06220 i += lang_specific_extra_outfiles;
06221 outfiles = (const char **) xcalloc (i, sizeof (char *));
06222
06223
06224
06225 explicit_link_files = xcalloc (1, n_infiles);
06226
06227 for (i = 0; (int) i < n_infiles; i++)
06228 {
06229 int this_file_error = 0;
06230
06231
06232
06233 input_file_number = i;
06234 set_input (infiles[i].name);
06235
06236
06237
06238 outfiles[i] = input_filename;
06239
06240
06241
06242 input_file_compiler
06243 = lookup_compiler (infiles[i].name, input_filename_length,
06244 infiles[i].language);
06245
06246 if (input_file_compiler)
06247 {
06248
06249
06250 if (input_file_compiler->spec[0] == '#')
06251 {
06252 error ("%s: %s compiler not installed on this system",
06253 input_filename, &input_file_compiler->spec[1]);
06254 this_file_error = 1;
06255 }
06256 else
06257 {
06258 value = do_spec (input_file_compiler->spec);
06259 if (value < 0)
06260 this_file_error = 1;
06261 }
06262 }
06263
06264
06265
06266
06267 else
06268 explicit_link_files[i] = 1;
06269
06270
06271
06272
06273 if (this_file_error)
06274 {
06275 delete_failure_queue ();
06276 error_count++;
06277 }
06278
06279 clear_failure_queue ();
06280 }
06281
06282
06283
06284
06285 if (n_infiles > 0)
06286 set_input (infiles[0].name);
06287
06288 if (error_count == 0)
06289 {
06290
06291
06292 input_file_number = n_infiles;
06293 if (lang_specific_pre_link ())
06294 error_count++;
06295 }
06296
06297
06298
06299 if (error_count == 0)
06300 {
06301 int tmp = execution_count;
06302
06303
06304 if (! strcmp (linker_name_spec, "collect2"))
06305 {
06306 char *s = find_a_file (&exec_prefixes, "collect2", X_OK, 0);
06307 if (s == NULL)
06308 linker_name_spec = "ld";
06309 }
06310
06311
06312 putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH");
06313 putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV);
06314
06315 value = do_spec (link_command_spec);
06316 if (value < 0)
06317 error_count = 1;
06318 linker_was_run = (tmp != execution_count);
06319 }
06320
06321
06322
06323
06324 if (! linker_was_run && error_count == 0)
06325 for (i = 0; (int) i < n_infiles; i++)
06326 if (explicit_link_files[i])
06327 error ("%s: linker input file unused because linking not done",
06328 outfiles[i]);
06329
06330
06331
06332 if (error_count)
06333 delete_failure_queue ();
06334 delete_temp_files ();
06335
06336 if (print_help_list)
06337 {
06338 printf (("\nFor bug reporting instructions, please see:\n"));
06339 printf ("%s\n", bug_report_url);
06340 }
06341
06342 return (signal_count != 0 ? 2
06343 : error_count > 0 ? (pass_exit_codes ? greatest_status : 1)
06344 : 0);
06345 }
06346
06347
06348
06349
06350
06351 static struct compiler *
06352 lookup_compiler (name, length, language)
06353 const char *name;
06354 size_t length;
06355 const char *language;
06356 {
06357 struct compiler *cp;
06358
06359
06360 if (language != 0 && language[0] == '*')
06361 return 0;
06362
06363
06364 if (language != 0)
06365 {
06366 for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
06367 if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
06368 return cp;
06369
06370 error ("language %s not recognized", language);
06371 return 0;
06372 }
06373
06374
06375 for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
06376 {
06377 if (
06378 (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
06379 || (strlen (cp->suffix) < length
06380
06381 && !strcmp (cp->suffix,
06382 name + length - strlen (cp->suffix))
06383 ))
06384 break;
06385 }
06386
06387 #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
06388
06389 if (cp < compilers)
06390 for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
06391 {
06392 if (
06393 (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
06394 || (strlen (cp->suffix) < length
06395
06396 && ((!strcmp (cp->suffix,
06397 name + length - strlen (cp->suffix))
06398 || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
06399 && !strcasecmp (cp->suffix,
06400 name + length - strlen (cp->suffix)))
06401 ))
06402 break;
06403 }
06404 #endif
06405
06406 if (cp >= compilers)
06407 {
06408 if (cp->spec[0] != '@')
06409
06410 return cp;
06411
06412
06413
06414
06415 return lookup_compiler (NULL, 0, cp->spec + 1);
06416 }
06417 return 0;
06418 }
06419
06420 static char *
06421 save_string (s, len)
06422 const char *s;
06423 int len;
06424 {
06425 char *result = xmalloc (len + 1);
06426
06427 memcpy (result, s, len);
06428 result[len] = 0;
06429 return result;
06430 }
06431
06432 void
06433 pfatal_with_name (name)
06434 const char *name;
06435 {
06436 perror_with_name (name);
06437 delete_temp_files ();
06438 exit (1);
06439 }
06440
06441 static void
06442 perror_with_name (name)
06443 const char *name;
06444 {
06445 error ("%s: %s", name, xstrerror (errno));
06446 }
06447
06448 static void
06449 pfatal_pexecute (errmsg_fmt, errmsg_arg)
06450 const char *errmsg_fmt;
06451 const char *errmsg_arg;
06452 {
06453 if (errmsg_arg)
06454 {
06455 int save_errno = errno;
06456
06457
06458 char *msg = xmalloc (strlen (errmsg_fmt) + strlen (errmsg_arg));
06459 sprintf (msg, errmsg_fmt, errmsg_arg);
06460 errmsg_fmt = msg;
06461
06462 errno = save_errno;
06463 }
06464
06465 pfatal_with_name (errmsg_fmt);
06466 }
06467
06468
06469
06470 void
06471 fancy_abort ()
06472 {
06473 fatal ("internal gcc abort");
06474 }
06475
06476
06477
06478 void
06479 fatal VPARAMS ((const char *msgid, ...))
06480 {
06481 VA_OPEN (ap, msgid);
06482 VA_FIXEDARG (ap, const char *, msgid);
06483
06484 fprintf (stderr, "%s: ", programname);
06485 vfprintf (stderr, _(msgid), ap);
06486 VA_CLOSE (ap);
06487 fprintf (stderr, "\n");
06488 delete_temp_files ();
06489 exit (1);
06490 }
06491
06492 void
06493 error VPARAMS ((const char *msgid, ...))
06494 {
06495 VA_OPEN (ap, msgid);
06496 VA_FIXEDARG (ap, const char *, msgid);
06497
06498 fprintf (stderr, "%s: ", programname);
06499 vfprintf (stderr, _(msgid), ap);
06500 VA_CLOSE (ap);
06501
06502 fprintf (stderr, "\n");
06503 }
06504
06505 static void
06506 notice VPARAMS ((const char *msgid, ...))
06507 {
06508 VA_OPEN (ap, msgid);
06509 VA_FIXEDARG (ap, const char *, msgid);
06510
06511 vfprintf (stderr, _(msgid), ap);
06512 VA_CLOSE (ap);
06513 }
06514
06515 static void
06516 validate_all_switches ()
06517 {
06518 struct compiler *comp;
06519 const char *p;
06520 char c;
06521 struct spec_list *spec;
06522
06523 for (comp = compilers; comp->spec; comp++)
06524 {
06525 p = comp->spec;
06526 while ((c = *p++))
06527 if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
06528
06529 validate_switches (p + 1);
06530 }
06531
06532
06533 for (spec = specs; spec; spec = spec->next)
06534 {
06535 p = *(spec->ptr_spec);
06536 while ((c = *p++))
06537 if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
06538
06539 validate_switches (p + 1);
06540 }
06541
06542 p = link_command_spec;
06543 while ((c = *p++))
06544 if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
06545
06546 validate_switches (p + 1);
06547 }
06548
06549
06550
06551
06552 static void
06553 validate_switches (start)
06554 const char *start;
06555 {
06556 const char *p = start;
06557 const char *filter;
06558 int i;
06559 int suffix;
06560
06561 if (*p == '|')
06562 ++p;
06563
06564 next_member:
06565 if (*p == '!')
06566 ++p;
06567
06568 suffix = 0;
06569 if (*p == '.')
06570 suffix = 1, ++p;
06571
06572 filter = p;
06573 while (*p != ':' && *p != '}' && *p != '|' && *p != '&')
06574 p++;
06575
06576 if (suffix)
06577 ;
06578 else if (p[-1] == '*')
06579 {
06580
06581 for (i = 0; i < n_switches; i++)
06582 if (!strncmp (switches[i].part1, filter, p - filter - 1))
06583 switches[i].validated = 1;
06584 }
06585 else
06586 {
06587
06588 for (i = 0; i < n_switches; i++)
06589 {
06590 if (!strncmp (switches[i].part1, filter, p - filter)
06591 && switches[i].part1[p - filter] == 0)
06592 switches[i].validated = 1;
06593 }
06594 }
06595
06596 if (*p++ == '|' || p[-1] == '&')
06597 goto next_member;
06598 }
06599
06600 struct mdswitchstr
06601 {
06602 const char *str;
06603 int len;
06604 };
06605
06606 static struct mdswitchstr *mdswitches;
06607 static int n_mdswitches;
06608
06609
06610
06611
06612 static int
06613 used_arg (p, len)
06614 const char *p;
06615 int len;
06616 {
06617 struct mswitchstr
06618 {
06619 const char *str;
06620 const char *replace;
06621 int len;
06622 int rep_len;
06623 };
06624
06625 static struct mswitchstr *mswitches;
06626 static int n_mswitches;
06627 int i, j;
06628
06629 if (!mswitches)
06630 {
06631 struct mswitchstr *matches;
06632 const char *q;
06633 int cnt = 0;
06634
06635
06636
06637 for (q = multilib_matches; *q != '\0'; q++)
06638 if (*q == ';')
06639 cnt++;
06640
06641 matches =
06642 (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
06643 i = 0;
06644 q = multilib_matches;
06645 while (*q != '\0')
06646 {
06647 matches[i].str = q;
06648 while (*q != ' ')
06649 {
06650 if (*q == '\0')
06651 abort ();
06652 q++;
06653 }
06654 matches[i].len = q - matches[i].str;
06655
06656 matches[i].replace = ++q;
06657 while (*q != ';' && *q != '\0')
06658 {
06659 if (*q == ' ')
06660 abort ();
06661 q++;
06662 }
06663 matches[i].rep_len = q - matches[i].replace;
06664 i++;
06665 if (*q == ';')
06666 q++;
06667 }
06668
06669
06670
06671
06672
06673 mswitches
06674 = (struct mswitchstr *)
06675 xmalloc (sizeof (struct mswitchstr)
06676 * (n_mdswitches + (n_switches ? n_switches : 1)));
06677 for (i = 0; i < n_switches; i++)
06678 {
06679 int xlen = strlen (switches[i].part1);
06680 for (j = 0; j < cnt; j++)
06681 if (xlen == matches[j].len
06682 && ! strncmp (switches[i].part1, matches[j].str, xlen))
06683 {
06684 mswitches[n_mswitches].str = matches[j].replace;
06685 mswitches[n_mswitches].len = matches[j].rep_len;
06686 mswitches[n_mswitches].replace = (char *) 0;
06687 mswitches[n_mswitches].rep_len = 0;
06688 n_mswitches++;
06689 break;
06690 }
06691 }
06692
06693
06694
06695
06696 for (i = 0; i < n_mdswitches; i++)
06697 {
06698 const char *r;
06699
06700 for (q = multilib_options; *q != '\0'; q++)
06701 {
06702 while (*q == ' ')
06703 q++;
06704
06705 r = q;
06706 while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
06707 || strchr (" /", q[mdswitches[i].len]) == NULL)
06708 {
06709 while (*q != ' ' && *q != '/' && *q != '\0')
06710 q++;
06711 if (*q != '/')
06712 break;
06713 q++;
06714 }
06715
06716 if (*q != ' ' && *q != '\0')
06717 {
06718 while (*r != ' ' && *r != '\0')
06719 {
06720 q = r;
06721 while (*q != ' ' && *q != '/' && *q != '\0')
06722 q++;
06723
06724 if (used_arg (r, q - r))
06725 break;
06726
06727 if (*q != '/')
06728 {
06729 mswitches[n_mswitches].str = mdswitches[i].str;
06730 mswitches[n_mswitches].len = mdswitches[i].len;
06731 mswitches[n_mswitches].replace = (char *) 0;
06732 mswitches[n_mswitches].rep_len = 0;
06733 n_mswitches++;
06734 break;
06735 }
06736
06737 r = q + 1;
06738 }
06739 break;
06740 }
06741 }
06742 }
06743 }
06744
06745 for (i = 0; i < n_mswitches; i++)
06746 if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
06747 return 1;
06748
06749 return 0;
06750 }
06751
06752 static int
06753 default_arg (p, len)
06754 const char *p;
06755 int len;
06756 {
06757 int i;
06758
06759 for (i = 0; i < n_mdswitches; i++)
06760 if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
06761 return 1;
06762
06763 return 0;
06764 }
06765
06766
06767
06768
06769
06770
06771
06772
06773
06774
06775
06776
06777 static void
06778 set_multilib_dir ()
06779 {
06780 const char *p;
06781 unsigned int this_path_len;
06782 const char *this_path, *this_arg;
06783 const char *start, *end;
06784 int not_arg;
06785 int ok, ndfltok, first;
06786
06787 n_mdswitches = 0;
06788 start = multilib_defaults;
06789 while (*start == ' ' || *start == '\t')
06790 start++;
06791 while (*start != '\0')
06792 {
06793 n_mdswitches++;
06794 while (*start != ' ' && *start != '\t' && *start != '\0')
06795 start++;
06796 while (*start == ' ' || *start == '\t')
06797 start++;
06798 }
06799
06800 if (n_mdswitches)
06801 {
06802 int i = 0;
06803
06804 mdswitches
06805 = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr)
06806 * n_mdswitches);
06807 for (start = multilib_defaults; *start != '\0'; start = end + 1)
06808 {
06809 while (*start == ' ' || *start == '\t')
06810 start++;
06811
06812 if (*start == '\0')
06813 break;
06814
06815 for (end = start + 1;
06816 *end != ' ' && *end != '\t' && *end != '\0'; end++)
06817 ;
06818
06819 obstack_grow (&multilib_obstack, start, end - start);
06820 obstack_1grow (&multilib_obstack, 0);
06821 mdswitches[i].str = obstack_finish (&multilib_obstack);
06822 mdswitches[i++].len = end - start;
06823
06824 if (*end == '\0')
06825 break;
06826 }
06827 }
06828
06829 p = multilib_exclusions;
06830 while (*p != '\0')
06831 {
06832
06833 if (*p == '\n')
06834 {
06835 ++p;
06836 continue;
06837 }
06838
06839
06840 ok = 1;
06841 while (*p != ';')
06842 {
06843 if (*p == '\0')
06844 abort ();
06845
06846 if (! ok)
06847 {
06848 ++p;
06849 continue;
06850 }
06851
06852 this_arg = p;
06853 while (*p != ' ' && *p != ';')
06854 {
06855 if (*p == '\0')
06856 abort ();
06857 ++p;
06858 }
06859
06860 if (*this_arg != '!')
06861 not_arg = 0;
06862 else
06863 {
06864 not_arg = 1;
06865 ++this_arg;
06866 }
06867
06868 ok = used_arg (this_arg, p - this_arg);
06869 if (not_arg)
06870 ok = ! ok;
06871
06872 if (*p == ' ')
06873 ++p;
06874 }
06875
06876 if (ok)
06877 return;
06878
06879 ++p;
06880 }
06881
06882 first = 1;
06883 p = multilib_select;
06884 while (*p != '\0')
06885 {
06886
06887 if (*p == '\n')
06888 {
06889 ++p;
06890 continue;
06891 }
06892
06893
06894 this_path = p;
06895 while (*p != ' ')
06896 {
06897 if (*p == '\0')
06898 abort ();
06899 ++p;
06900 }
06901 this_path_len = p - this_path;
06902
06903
06904 ok = 1;
06905 ndfltok = 1;
06906 ++p;
06907 while (*p != ';')
06908 {
06909 if (*p == '\0')
06910 abort ();
06911
06912 if (! ok)
06913 {
06914 ++p;
06915 continue;
06916 }
06917
06918 this_arg = p;
06919 while (*p != ' ' && *p != ';')
06920 {
06921 if (*p == '\0')
06922 abort ();
06923 ++p;
06924 }
06925
06926 if (*this_arg != '!')
06927 not_arg = 0;
06928 else
06929 {
06930 not_arg = 1;
06931 ++this_arg;
06932 }
06933
06934
06935
06936
06937
06938
06939
06940
06941 ok = used_arg (this_arg, p - this_arg);
06942 if (not_arg)
06943 ok = ! ok;
06944
06945 if (! ok)
06946 ndfltok = 0;
06947
06948 if (default_arg (this_arg, p - this_arg))
06949 ok = 1;
06950
06951 if (*p == ' ')
06952 ++p;
06953 }
06954
06955 if (ok && first)
06956 {
06957 if (this_path_len != 1
06958 || this_path[0] != '.')
06959 {
06960 char *new_multilib_dir = xmalloc (this_path_len + 1);
06961 char *q;
06962
06963 strncpy (new_multilib_dir, this_path, this_path_len);
06964 new_multilib_dir[this_path_len] = '\0';
06965 q = strchr (new_multilib_dir, ':');
06966 if (q != NULL)
06967 *q = '\0';
06968 multilib_dir = new_multilib_dir;
06969 }
06970 first = 0;
06971 }
06972
06973 if (ndfltok)
06974 {
06975 const char *q = this_path, *end = this_path + this_path_len;
06976
06977 while (q < end && *q != ':')
06978 q++;
06979 if (q < end)
06980 {
06981 char *new_multilib_os_dir = xmalloc (end - q);
06982 memcpy (new_multilib_os_dir, q + 1, end - q - 1);
06983 new_multilib_os_dir[end - q - 1] = '\0';
06984 multilib_os_dir = new_multilib_os_dir;
06985 break;
06986 }
06987 }
06988
06989 ++p;
06990 }
06991
06992 if (multilib_dir == NULL && multilib_os_dir != NULL
06993 && strcmp (multilib_os_dir, ".") == 0)
06994 {
06995 free ((char *) multilib_os_dir);
06996 multilib_os_dir = NULL;
06997 }
06998 else if (multilib_dir != NULL && multilib_os_dir == NULL)
06999 multilib_os_dir = multilib_dir;
07000 }
07001
07002
07003
07004
07005
07006
07007
07008
07009
07010
07011
07012 static void
07013 print_multilib_info ()
07014 {
07015 const char *p = multilib_select;
07016 const char *last_path = 0, *this_path;
07017 int skip;
07018 unsigned int last_path_len = 0;
07019
07020 while (*p != '\0')
07021 {
07022 skip = 0;
07023
07024 if (*p == '\n')
07025 {
07026 ++p;
07027 continue;
07028 }
07029
07030
07031 this_path = p;
07032 while (*p != ' ')
07033 {
07034 if (*p == '\0')
07035 abort ();
07036 ++p;
07037 }
07038
07039
07040
07041
07042 if (this_path[0] == '.' && this_path[1] == ':')
07043 skip = 1;
07044
07045
07046
07047
07048 {
07049 const char *e = multilib_exclusions;
07050 const char *this_arg;
07051
07052 while (*e != '\0')
07053 {
07054 int m = 1;
07055
07056 if (*e == '\n')
07057 {
07058 ++e;
07059 continue;
07060 }
07061
07062
07063 while (*e != ';')
07064 {
07065 const char *q;
07066 int mp = 0;
07067
07068 if (*e == '\0')
07069 abort ();
07070
07071 if (! m)
07072 {
07073 ++e;
07074 continue;
07075 }
07076
07077 this_arg = e;
07078
07079 while (*e != ' ' && *e != ';')
07080 {
07081 if (*e == '\0')
07082 abort ();
07083 ++e;
07084 }
07085
07086 q = p + 1;
07087 while (*q != ';')
07088 {
07089 const char *arg;
07090 int len = e - this_arg;
07091
07092 if (*q == '\0')
07093 abort ();
07094
07095 arg = q;
07096
07097 while (*q != ' ' && *q != ';')
07098 {
07099 if (*q == '\0')
07100 abort ();
07101 ++q;
07102 }
07103
07104 if (! strncmp (arg, this_arg, (len < q - arg) ? q - arg : len) ||
07105 default_arg (this_arg, e - this_arg))
07106 {
07107 mp = 1;
07108 break;
07109 }
07110
07111 if (*q == ' ')
07112 ++q;
07113 }
07114
07115 if (! mp)
07116 m = 0;
07117
07118 if (*e == ' ')
07119 ++e;
07120 }
07121
07122 if (m)
07123 {
07124 skip = 1;
07125 break;
07126 }
07127
07128 if (*e != '\0')
07129 ++e;
07130 }
07131 }
07132
07133 if (! skip)
07134 {
07135
07136 skip = (last_path != 0 && (unsigned int) (p - this_path) == last_path_len
07137 && ! strncmp (last_path, this_path, last_path_len));
07138
07139 last_path = this_path;
07140 last_path_len = p - this_path;
07141 }
07142
07143
07144
07145
07146 if (! skip)
07147 {
07148 const char *q;
07149
07150 q = p + 1;
07151 while (*q != ';')
07152 {
07153 const char *arg;
07154
07155 if (*q == '\0')
07156 abort ();
07157
07158 if (*q == '!')
07159 arg = NULL;
07160 else
07161 arg = q;
07162
07163 while (*q != ' ' && *q != ';')
07164 {
07165 if (*q == '\0')
07166 abort ();
07167 ++q;
07168 }
07169
07170 if (arg != NULL
07171 && default_arg (arg, q - arg))
07172 {
07173 skip = 1;
07174 break;
07175 }
07176
07177 if (*q == ' ')
07178 ++q;
07179 }
07180 }
07181
07182 if (! skip)
07183 {
07184 const char *p1;
07185
07186 for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
07187 putchar (*p1);
07188 putchar (';');
07189 }
07190
07191 ++p;
07192 while (*p != ';')
07193 {
07194 int use_arg;
07195
07196 if (*p == '\0')
07197 abort ();
07198
07199 if (skip)
07200 {
07201 ++p;
07202 continue;
07203 }
07204
07205 use_arg = *p != '!';
07206
07207 if (use_arg)
07208 putchar ('@');
07209
07210 while (*p != ' ' && *p != ';')
07211 {
07212 if (*p == '\0')
07213 abort ();
07214 if (use_arg)
07215 putchar (*p);
07216 ++p;
07217 }
07218
07219 if (*p == ' ')
07220 ++p;
07221 }
07222
07223 if (! skip)
07224 {
07225
07226 if (multilib_extra && *multilib_extra)
07227 {
07228 int print_at = TRUE;
07229 const char *q;
07230
07231 for (q = multilib_extra; *q != '\0'; q++)
07232 {
07233 if (*q == ' ')
07234 print_at = TRUE;
07235 else
07236 {
07237 if (print_at)
07238 putchar ('@');
07239 putchar (*q);
07240 print_at = FALSE;
07241 }
07242 }
07243 }
07244
07245 putchar ('\n');
07246 }
07247
07248 ++p;
07249 }
07250 }
07251
07252
07253
07254
07255
07256
07257
07258
07259
07260 static const char *
07261 if_exists_spec_function (argc, argv)
07262 int argc;
07263 const char **argv;
07264 {
07265
07266 if (argc == 1 && IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
07267 return argv[0];
07268
07269 return NULL;
07270 }
07271
07272
07273
07274
07275
07276
07277 static const char *
07278 if_exists_else_spec_function (argc, argv)
07279 int argc;
07280 const char **argv;
07281 {
07282
07283 if (argc != 2)
07284 return NULL;
07285
07286 if (IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
07287 return argv[0];
07288
07289 return argv[1];
07290 }