X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgcc.c;h=09b03326a681eba2df86ddd3a9a9fa984b2f7af0;hb=1526a87c04c6c718746cffdd9d0221c49ed39d47;hp=c2c1af628094838ea33a845d419c5654b71307e6;hpb=42fe96d7618d3e9eba47025a14e760010a85502d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/gcc.c b/gcc/gcc.c index c2c1af62809..09b03326a68 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -121,14 +121,7 @@ static char dir_separator_str[] = {DIR_SEPARATOR, 0}; #define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME) #endif -extern char *choose_temp_base PROTO((void)); - -#ifndef HAVE_STRERROR -extern int sys_nerr; -extern char *sys_errlist[]; -#else -extern char *strerror(); -#endif +extern char *my_strerror PROTO((int)); #ifndef HAVE_KILL #define kill(p,s) raise(s) @@ -232,7 +225,7 @@ static int check_live_switch PROTO((int, int)); static char *handle_braces PROTO((char *)); static char *save_string PROTO((char *, int)); static char *concat PVPROTO((char *, ...)); -static int do_spec PROTO((char *)); +extern int do_spec PROTO((char *)); static int do_spec_1 PROTO((char *, int, char *)); static char *find_file PROTO((char *)); static int is_directory PROTO((char *, char *, int)); @@ -254,7 +247,14 @@ char *xmalloc (); char *xrealloc (); #ifdef LANG_SPECIFIC_DRIVER +/* Called before processing to change/add/remove arguments. */ extern void lang_specific_driver PROTO ((void (*) PVPROTO((char *, ...)), int *, char ***, int *)); + +/* Called before linking. Returns 0 on success and -1 on failure. */ +extern int lang_specific_pre_link (); + +/* Number of extra output files that lang_specific_pre_link may generate. */ +extern int lang_specific_extra_outfiles; #endif /* Specs are strings containing lines, each of which (if not blank) @@ -356,6 +356,8 @@ or with constant text in a single argument. %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'. %{.S:X} substitutes X, but only if processing a file with suffix S. %{!.S:X} substitutes X, but only if NOT processing a file with suffix S. + %{S|P:X} substitutes X if either -S or -P was given to CC. This may be + combined with ! and . as above binding stronger than the OR. %(Spec) processes a specification defined in a specs file as *Spec: %[Spec] as above, but put __ around -D arguments @@ -369,8 +371,9 @@ constructs. If another value of -O or the negated form of a -f, -m, or value is ignored, except with {S*} where S is just one letter; this passes all matching options. -The character | is used to indicate that a command should be piped to -the following command, but only if -pipe is specified. +The character | at the beginning of the predicate text is used to indicate +that a command should be piped to the following command, but only if -pipe +is specified. Note that it is built into CC which switches take arguments and which do not. You might think it would be useful to generalize this to @@ -590,7 +593,41 @@ static struct compiler default_compilers[] = /* Next come the entries for C. */ {".c", {"@c"}}, {"@c", - {"cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + { +#if USE_CPPLIB + "%{E|M|MM:cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ + -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ + %{ansi:-trigraphs -D__STRICT_ANSI__}\ + %{!undef:%{!ansi:%p} %P} %{trigraphs} \ + %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ + %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ + %i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}\ + %{!E:%{!M:%{!MM:cc1 %i %1 \ + -lang-c%{ansi:89} %{nostdinc*} %{A*} %{I*} %I\ + %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\ + %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ + -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ + %{ansi:-trigraphs -D__STRICT_ANSI__}\ + %{!undef:%{!ansi:%p} %P} %{trigraphs} \ + %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ + %{H} %C %{D*} %{U*} %{i*} %Z\ + %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\ + %{aux-info*}\ + %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ + %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ + %{!S:as %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ + %{!pipe:%g.s} %A\n }}}}" + }}, +#else /* ! USE_CPPLIB */ + "cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ %{C:%{!E:%eGNU C does not support -C without using -E}}\ %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ @@ -601,7 +638,7 @@ static struct compiler default_compilers[] = %{traditional-cpp:-traditional}\ %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \ + "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \ %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\ @@ -610,7 +647,9 @@ static struct compiler default_compilers[] = %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ %{!S:as %a %Y\ %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, + %{!pipe:%g.s} %A\n }}}}" + }}, +#endif /* ! USE_CPPLIB */ {"-", {"%{E:cpp -lang-c%{ansi:89} %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ %{C:%{!E:%eGNU C does not support -C without using -E}}\ @@ -1225,7 +1264,13 @@ static int argbuf_length; static int argbuf_index; +/* We want this on by default all the time now. */ +#define MKTEMP_EACH_FILE + #ifdef MKTEMP_EACH_FILE + +extern char *make_temp_file PROTO((void)); + /* This is the list of suffixes and codes (%g/%u/%U) and the associated temp file. */ @@ -1237,8 +1282,11 @@ static struct temp_name { int filename_length; /* strlen (filename). */ struct temp_name *next; } *temp_names; +#else +extern char *choose_temp_base PROTO((void)); #endif + /* Number of commands executed so far. */ static int execution_count; @@ -3111,9 +3159,9 @@ process_command (argc, argv) sans all directory names, and basename_length is the number of characters starting there excluding the suffix .c or whatever. */ -static char *input_filename; +char *input_filename; static int input_file_number; -static size_t input_filename_length; +size_t input_filename_length; static int basename_length; static char *input_basename; static char *input_suffix; @@ -3143,7 +3191,7 @@ static int input_from_pipe; /* Process the spec SPEC and run the commands specified therein. Returns 0 if the spec is successfully processed; -1 if failed. */ -static int +int do_spec (spec) char *spec; { @@ -3469,7 +3517,7 @@ do_spec_1 (spec, inswitch, soft_matched_part) t->length = p - suffix; t->suffix = save_string (suffix, p - suffix); t->unique = (c != 'g'); - temp_filename = choose_temp_base (); + temp_filename = make_temp_file (); temp_filename_length = strlen (temp_filename); t->filename = temp_filename; t->filename_length = temp_filename_length; @@ -4008,11 +4056,10 @@ static char * handle_braces (p) register char *p; { - register char *q; - char *filter; + char *filter, *body = NULL, *endbody; int pipe_p = 0; - int negate = 0; - int suffix = 0; + int negate; + int suffix; int include_blanks = 1; if (*p == '^') @@ -4025,6 +4072,9 @@ handle_braces (p) This is used in %{|!pipe:...}. */ pipe_p = 1, ++p; +next_member: + negate = suffix = 0; + if (*p == '!') /* A `!' after the open-brace negates the condition: succeed if the specified switch is not present. */ @@ -4041,24 +4091,36 @@ handle_braces (p) } filter = p; - while (*p != ':' && *p != '}') p++; - if (*p != '}') + while (*p != ':' && *p != '}' && *p != '|') p++; + + if (*p == '|' && pipe_p) + abort (); + + if (!body) { - register int count = 1; - q = p + 1; - while (count > 0) - { - if (*q == '{') - count++; - else if (*q == '}') - count--; - else if (*q == 0) - abort (); - q++; + if (*p != '}') + { + register int count = 1; + register char *q = p; + + while (*q++ != ':') continue; + body = q; + + while (count > 0) + { + if (*q == '{') + count++; + else if (*q == '}') + count--; + else if (*q == 0) + abort (); + q++; + } + endbody = q; } + else + body = p, endbody = p+1; } - else - q = p + 1; if (suffix) { @@ -4066,14 +4128,12 @@ handle_braces (p) && strlen (input_suffix) == p - filter && strncmp (input_suffix, filter, p - filter) == 0); - if (p[0] == '}') + if (body[0] == '}') abort (); if (negate != found - && do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0) + && do_spec_1 (save_string (body, endbody-body-1), 0, NULL_PTR) < 0) return 0; - - return q; } else if (p[-1] == '*' && p[0] == '}') { @@ -4096,11 +4156,11 @@ handle_braces (p) if (p[-1] == '*' && !negate) { int substitution; - char *r = p; + char *r = body; /* First see whether we have %*. */ substitution = 0; - while (r < q) + while (r < endbody) { if (*r == '%' && r[1] == '*') substitution = 1; @@ -4114,7 +4174,7 @@ handle_braces (p) in the text that follows the colon. */ unsigned hard_match_len = p - filter - 1; - char *string = save_string (p + 1, q - p - 2); + char *string = save_string (body, endbody - body - 1); for (i = 0; i < n_switches; i++) if (!strncmp (switches[i].part1, filter, hard_match_len) @@ -4125,7 +4185,10 @@ handle_braces (p) give_switch (i, 1, 1); } - return q; + /* We didn't match. Try again. */ + if (*p++ == '|') + goto next_member; + return endbody; } } @@ -4159,7 +4222,7 @@ handle_braces (p) } } - /* If it is as desired (present for %{s...}, absent for %{-s...}) + /* If it is as desired (present for %{s...}, absent for %{!s...}) then substitute either the switch or the specified conditional text. */ if (present != negate) @@ -4170,7 +4233,8 @@ handle_braces (p) } else { - if (do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0) + if (do_spec_1 (save_string (body, endbody - body - 1), + 0, NULL_PTR) < 0) return 0; } } @@ -4179,10 +4243,15 @@ handle_braces (p) /* Here if a %{|...} conditional fails: output a minus sign, which means "standard output" or "standard input". */ do_spec_1 ("-", 0, NULL_PTR); + return endbody; } } - return q; + /* We didn't match; try again. */ + if (*p++ == '|') + goto next_member; + + return endbody; } /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch @@ -4480,8 +4549,10 @@ main (argc, argv) /* Choose directory for temp files. */ +#ifndef MKTEMP_EACH_FILE temp_filename = choose_temp_base (); temp_filename_length = strlen (temp_filename); +#endif /* Make a table of what switches there are (switches, n_switches). Make a table of specified input files (infiles, n_infiles). @@ -4739,7 +4810,11 @@ main (argc, argv) /* Make a place to record the compiler output file names that correspond to the input files. */ - outfiles = (char **) xmalloc (n_infiles * sizeof (char *)); + i = n_infiles; +#ifdef LANG_SPECIFIC_DRIVER + i += lang_specific_extra_outfiles; +#endif + outfiles = (char **) xmalloc (i * sizeof (char *)); bzero ((char *) outfiles, n_infiles * sizeof (char *)); /* Record which files were specified explicitly as link input. */ @@ -4835,6 +4910,12 @@ main (argc, argv) clear_failure_queue (); } +#ifdef LANG_SPECIFIC_DRIVER + if (error_count == 0 + && lang_specific_pre_link ()) + error_count++; +#endif + /* Run ld to link all the compiler output files. */ if (error_count == 0)