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