From 467829319b1fd38f35b497a6ebb34faebd0c0046 Mon Sep 17 00:00:00 2001 From: dnovillo Date: Fri, 17 Apr 2009 21:11:46 +0000 Subject: [PATCH] PR 31567 * gcc.c (create_at_file): New. (compile_input_file_p): New. (do_spec_1): Use @args files for %i. Use create_at_file for %o. * main.c (main): Update call to toplev_main. * toplev.c (toplev_main): Change signature. Call expandargv. * toplev.h (toplev_main): Change signature. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146292 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++ gcc/gcc.c | 105 ++++++++++++++++++++++++++++++++++++++++++---------------- gcc/main.c | 2 +- gcc/toplev.c | 8 +++-- gcc/toplev.h | 2 +- 5 files changed, 93 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7134327..cdf5bb0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2009-04-17 Rafael Avila de Espindola + + PR 31567 + * gcc.c (create_at_file): New. + (compile_input_file_p): New. + (do_spec_1): Use @args files for %i. Use create_at_file for %o. + * main.c (main): Update call to toplev_main. + * toplev.c (toplev_main): Change signature. Call expandargv. + * toplev.h (toplev_main): Change signature. + 2009-04-17 Eric Botcazou * dwarf2out.c (field_byte_offset): Use the type size as the field size diff --git a/gcc/gcc.c b/gcc/gcc.c index 5c697ea0..53325b2 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -4741,6 +4741,49 @@ spec_path (char *path, void *data) return NULL; } +/* Create a temporary FILE with the contents of ARGV. Add @FILE to the + argument list. */ + +static void +create_at_file (char **argv) +{ + char *temp_file = make_temp_file (""); + char *at_argument = concat ("@", temp_file, NULL); + FILE *f = fopen (temp_file, "w"); + int status; + + if (f == NULL) + fatal ("could not open temporary response file %s", + temp_file); + + status = writeargv (argv, f); + + if (status) + fatal ("could not write to temporary response file %s", + temp_file); + + status = fclose (f); + + if (EOF == status) + fatal ("could not close temporary response file %s", + temp_file); + + store_arg (at_argument, 0, 0); + + record_temp_file (temp_file, !save_temps_flag, !save_temps_flag); +} + +/* True if we should compile INFILE. */ + +static bool +compile_input_file_p (struct infile *infile) +{ + if ((!infile->language) || (infile->language[0] != '*')) + if (infile->incompiler == input_file_compiler) + return true; + return false; +} + /* Process the sub-spec SPEC as a portion of a larger spec. This is like processing a whole spec except that we do not initialize at the beginning and we do not supply a @@ -5107,9 +5150,37 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) case 'i': if (combine_inputs) { - for (i = 0; (int) i < n_infiles; i++) - if ((!infiles[i].language) || (infiles[i].language[0] != '*')) - if (infiles[i].incompiler == input_file_compiler) + if (at_file_supplied) + { + /* We are going to expand `%i' to `@FILE', where FILE + is a newly-created temporary filename. The filenames + that would usually be expanded in place of %o will be + written to the temporary file. */ + char **argv; + int n_files = 0; + int j; + + for (i = 0; i < n_infiles; i++) + if (compile_input_file_p (&infiles[i])) + n_files++; + + argv = (char **) alloca (sizeof (char *) * (n_files + 1)); + + /* Copy the strings over. */ + for (i = 0, j = 0; i < n_infiles; i++) + if (compile_input_file_p (&infiles[i])) + { + argv[j] = CONST_CAST (char *, infiles[i].name); + infiles[i].compiled = true; + j++; + } + argv[j] = NULL; + + create_at_file (argv); + } + else + for (i = 0; (int) i < n_infiles; i++) + if (compile_input_file_p (&infiles[i])) { store_arg (infiles[i].name, 0, 0); infiles[i].compiled = true; @@ -5187,14 +5258,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) that would usually be expanded in place of %o will be written to the temporary file. */ - char *temp_file = make_temp_file (""); - char *at_argument; char **argv; - int n_files, j, status; - FILE *f; - - at_argument = concat ("@", temp_file, NULL); - store_arg (at_argument, 0, 0); + int n_files, j; /* Convert OUTFILES into a form suitable for writeargv. */ @@ -5213,25 +5278,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) } argv[j] = NULL; - f = fopen (temp_file, "w"); - - if (f == NULL) - fatal ("could not open temporary response file %s", - temp_file); - - status = writeargv (argv, f); - - if (status) - fatal ("could not write to temporary response file %s", - temp_file); - - status = fclose (f); - - if (EOF == status) - fatal ("could not close temporary response file %s", - temp_file); - - record_temp_file (temp_file, !save_temps_flag, !save_temps_flag); + create_at_file (argv); } else for (i = 0; i < max; i++) diff --git a/gcc/main.c b/gcc/main.c index fc5a4db..3e6c41c 100644 --- a/gcc/main.c +++ b/gcc/main.c @@ -32,5 +32,5 @@ int main (int argc, char **argv); int main (int argc, char **argv) { - return toplev_main (argc, (const char **) argv); + return toplev_main (argc, argv); } diff --git a/gcc/toplev.c b/gcc/toplev.c index 0f3d30b..bd709fc 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2261,16 +2261,18 @@ do_compile (void) It is not safe to call this function more than once. */ int -toplev_main (unsigned int argc, const char **argv) +toplev_main (int argc, char **argv) { - save_argv = argv; + expandargv (&argc, &argv); + + save_argv = (const char **) argv; /* Initialization of GCC's environment, and diagnostics. */ general_init (argv[0]); /* Parse the options and do minimal processing; basically just enough to default flags appropriately. */ - decode_options (argc, argv); + decode_options (argc, (const char **) argv); init_local_tick (); diff --git a/gcc/toplev.h b/gcc/toplev.h index 2324b06..15180c3 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #define skip_leading_substring(whole, part) \ (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part)) -extern int toplev_main (unsigned int, const char **); +extern int toplev_main (int, char **); extern int read_integral_parameter (const char *, const char *, const int); extern void strip_off_ending (char *, int); extern const char *trim_filename (const char *); -- 2.7.4