Commit 2091ff66 by Nathan Froyd

libiberty.h (writeargv): Declare.

include/
2007-05-07  Nathan Froyd  <froydnj@codesourcery.com>

	* libiberty.h (writeargv): Declare.

libiberty/
2007-05-07  Nathan Froyd  <froydnj@codesourcery.com>

	* argv.c (writeargv): New function.

gcc/
2007-05-07  Nathan Froyd  <froydnj@codesourcery.com>

	* gcc.c (at_file_supplied): New variable.
	(main): Set it if we expanded argv.
	(do_spec_1): Pass an @-file to the linker if we were called with
	an @-file argument and HAVE_GNU_LD.
	* collect2.c (at_file_supplied): New variable.
	(response_file): New variable.
	(collect_exit): Unlink response_file if necessary.
	(handler): Likewise.
	(do_wait): Likewise.
	(main): Set at_file_supplied if we expanded argv.
	(collect_execute): Pass an @-file to subprocesses if we were called
	with an @-file argument.
	* configure.ac: Add define for HAVE_GNU_LD.
	* configure: Regenerate.
	* config.in: Regenerate.

From-SVN: r124532
parent decc7c8a
2007-05-07 Nathan Froyd <froydnj@codesourcery.com>
* gcc.c (at_file_supplied): New variable.
(main): Set it if we expanded argv.
(do_spec_1): Pass an @-file to the linker if we were called with
an @-file argument and HAVE_GNU_LD.
* collect2.c (at_file_supplied): New variable.
(response_file): New variable.
(collect_exit): Unlink response_file if necessary.
(handler): Likewise.
(do_wait): Likewise.
(main): Set at_file_supplied if we expanded argv.
(collect_execute): Pass an @-file to subprocesses if we were called
with an @-file argument.
* configure.ac: Add define for HAVE_GNU_LD.
* configure: Regenerate.
* config.in: Regenerate.
2007-05-07 Naveen.H.S <naveen.hs@kpitcummins.com> 2007-05-07 Naveen.H.S <naveen.hs@kpitcummins.com>
* config/m32c/muldiv.md (mulhisi3_c): Limit the mode of the 2nd * config/m32c/muldiv.md (mulhisi3_c): Limit the mode of the 2nd
...@@ -28,7 +46,7 @@ ...@@ -28,7 +46,7 @@
ashrpsi3, lshrpsi3): Update shift count constraint. ashrpsi3, lshrpsi3): Update shift count constraint.
2007-05-07 Danny Smith <dannysmith@users.sourceforge.net> 2007-05-07 Danny Smith <dannysmith@users.sourceforge.net>
Nathan Froyd <froydnj@codesourcery.com Nathan Froyd <froydnj@codesourcery.com>
PR 22133 PR 22133
* c-incpath.c (add_path): Strip trailing path separators. * c-incpath.c (add_path): Strip trailing path separators.
......
/* Collect static initialization info into data structures that can be /* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines. traversed by C++ initialization and finalization routines.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com). Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com), Heavily modified by Michael Meissner (meissner@cygnus.com),
Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com). Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
...@@ -202,6 +202,9 @@ static struct head exports; /* list of exported symbols */ ...@@ -202,6 +202,9 @@ static struct head exports; /* list of exported symbols */
#endif #endif
static struct head frame_tables; /* list of frame unwind info tables */ static struct head frame_tables; /* list of frame unwind info tables */
static bool at_file_supplied; /* Whether to use @file arguments */
static char *response_file; /* Name of any current response file */
struct obstack temporary_obstack; struct obstack temporary_obstack;
char * temporary_firstobj; char * temporary_firstobj;
...@@ -302,6 +305,9 @@ collect_exit (int status) ...@@ -302,6 +305,9 @@ collect_exit (int status)
if (status != 0 && output_file != 0 && output_file[0]) if (status != 0 && output_file != 0 && output_file[0])
maybe_unlink (output_file); maybe_unlink (output_file);
if (response_file)
maybe_unlink (response_file);
exit (status); exit (status);
} }
...@@ -393,6 +399,9 @@ handler (int signo) ...@@ -393,6 +399,9 @@ handler (int signo)
maybe_unlink (export_file); maybe_unlink (export_file);
#endif #endif
if (response_file)
maybe_unlink (response_file);
signal (signo, SIG_DFL); signal (signo, SIG_DFL);
raise (signo); raise (signo);
} }
...@@ -793,7 +802,15 @@ main (int argc, char **argv) ...@@ -793,7 +802,15 @@ main (int argc, char **argv)
char **object_lst; char **object_lst;
const char **object; const char **object;
int first_file; int first_file;
int num_c_args = argc+9; int num_c_args;
char **old_argv;
old_argv = argv;
expandargv (&argc, &argv);
if (argv != old_argv)
at_file_supplied = 1;
num_c_args = argc + 9;
no_demangle = !! getenv ("COLLECT_NO_DEMANGLE"); no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
...@@ -1513,6 +1530,12 @@ do_wait (const char *prog, struct pex_obj *pex) ...@@ -1513,6 +1530,12 @@ do_wait (const char *prog, struct pex_obj *pex)
error ("%s returned %d exit status", prog, ret); error ("%s returned %d exit status", prog, ret);
collect_exit (ret); collect_exit (ret);
} }
if (response_file)
{
unlink (response_file);
response_file = NULL;
}
} }
...@@ -1525,6 +1548,47 @@ collect_execute (const char *prog, char **argv, const char *outname, ...@@ -1525,6 +1548,47 @@ collect_execute (const char *prog, char **argv, const char *outname,
struct pex_obj *pex; struct pex_obj *pex;
const char *errmsg; const char *errmsg;
int err; int err;
char *response_arg = NULL;
char *response_argv[3] ATTRIBUTE_UNUSED;
if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
{
/* If using @file arguments, create a temporary file and put the
contents of argv into it. Then change argv to an array corresponding
to a single argument @FILE, where FILE is the temporary filename. */
char **current_argv = argv + 1;
char *argv0 = argv[0];
int status;
FILE *f;
/* Note: we assume argv contains at least one element; this is
checked above. */
response_file = make_temp_file ("");
f = fopen (response_file, "w");
if (f == NULL)
fatal ("could not open response file %s", response_file);
status = writeargv (current_argv, f);
if (status)
fatal ("could not write to response file %s", response_file);
status = fclose (f);
if (EOF == status)
fatal ("could not close response file %s", response_file);
response_arg = concat ("@", response_file, NULL);
response_argv[0] = argv0;
response_argv[1] = response_arg;
response_argv[2] = NULL;
argv = response_argv;
}
if (vflag || debug) if (vflag || debug)
{ {
...@@ -1568,6 +1632,9 @@ collect_execute (const char *prog, char **argv, const char *outname, ...@@ -1568,6 +1632,9 @@ collect_execute (const char *prog, char **argv, const char *outname,
fatal (errmsg); fatal (errmsg);
} }
if (response_arg)
free (response_arg);
return pex; return pex;
} }
......
...@@ -869,6 +869,12 @@ ...@@ -869,6 +869,12 @@
#endif #endif
/* Define if using GNU ld. */
#ifndef USED_FOR_TARGET
#undef HAVE_GNU_LD
#endif
/* Define if you have the iconv() function. */ /* Define if you have the iconv() function. */
#ifndef USED_FOR_TARGET #ifndef USED_FOR_TARGET
#undef HAVE_ICONV #undef HAVE_ICONV
......
...@@ -1767,6 +1767,13 @@ _ACEOF ...@@ -1767,6 +1767,13 @@ _ACEOF
fi fi
gnu_ld=`if test x"$gnu_ld_flag" = x"yes"; then echo 1; else echo 0; fi`
cat >>confdefs.h <<_ACEOF
#define HAVE_GNU_LD $gnu_ld
_ACEOF
echo "$as_me:$LINENO: checking whether a default linker was specified" >&5 echo "$as_me:$LINENO: checking whether a default linker was specified" >&5
echo $ECHO_N "checking whether a default linker was specified... $ECHO_C" >&6 echo $ECHO_N "checking whether a default linker was specified... $ECHO_C" >&6
if test x"${DEFAULT_LINKER+set}" = x"set"; then if test x"${DEFAULT_LINKER+set}" = x"set"; then
...@@ -7665,7 +7672,7 @@ if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then ...@@ -7665,7 +7672,7 @@ if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then
else else
ac_prog_version=`$MAKEINFO --version 2>&1 | ac_prog_version=`$MAKEINFO --version 2>&1 |
sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'` sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
echo "configure:7668: version of makeinfo is $ac_prog_version" >&5 echo "configure:7675: version of makeinfo is $ac_prog_version" >&5
case $ac_prog_version in case $ac_prog_version in
'') gcc_cv_prog_makeinfo_modern=no;; '') gcc_cv_prog_makeinfo_modern=no;;
4.[4-9]*) 4.[4-9]*)
......
...@@ -206,6 +206,9 @@ if test x"${DEFAULT_LINKER+set}" = x"set"; then ...@@ -206,6 +206,9 @@ if test x"${DEFAULT_LINKER+set}" = x"set"; then
[Define to enable the use of a default linker.]) [Define to enable the use of a default linker.])
fi fi
gnu_ld=`if test x"$gnu_ld_flag" = x"yes"; then echo 1; else echo 0; fi`
AC_DEFINE_UNQUOTED(HAVE_GNU_LD, $gnu_ld, [Define if using GNU ld.])
AC_MSG_CHECKING([whether a default linker was specified]) AC_MSG_CHECKING([whether a default linker was specified])
if test x"${DEFAULT_LINKER+set}" = x"set"; then if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test x"$gnu_ld_flag" = x"no"; then if test x"$gnu_ld_flag" = x"no"; then
......
...@@ -127,6 +127,9 @@ static const char dir_separator_str[] = { DIR_SEPARATOR, 0 }; ...@@ -127,6 +127,9 @@ static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
/* Flag set by cppspec.c to 1. */ /* Flag set by cppspec.c to 1. */
int is_cpp_driver; int is_cpp_driver;
/* Flag set to non-zero if an @file argument has been supplied to gcc. */
static bool at_file_supplied;
/* Flag saying to pass the greatest exit code returned by a sub-process /* Flag saying to pass the greatest exit code returned by a sub-process
to the calling program. */ to the calling program. */
static int pass_exit_codes; static int pass_exit_codes;
...@@ -5009,9 +5012,63 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) ...@@ -5009,9 +5012,63 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
int max = n_infiles; int max = n_infiles;
max += lang_specific_extra_outfiles; max += lang_specific_extra_outfiles;
for (i = 0; i < max; i++) if (HAVE_GNU_LD && at_file_supplied)
if (outfiles[i]) {
store_arg (outfiles[i], 0, 0); /* We are going to expand `%o' 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 *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);
/* Convert OUTFILES into a form suitable for writeargv. */
/* Determine how many are non-NULL. */
for (n_files = 0, i = 0; i < max; i++)
n_files += outfiles[i] != NULL;
argv = alloca (sizeof (char *) * (n_files + 1));
/* Copy the strings over. */
for (i = 0, j = 0; i < max; i++)
if (outfiles[i])
{
argv[j] = (char *) outfiles[i];
j++;
}
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);
}
else
for (i = 0; i < max; i++)
if (outfiles[i])
store_arg (outfiles[i], 0, 0);
break; break;
} }
...@@ -6093,6 +6150,7 @@ main (int argc, char **argv) ...@@ -6093,6 +6150,7 @@ main (int argc, char **argv)
char *specs_file; char *specs_file;
const char *p; const char *p;
struct user_specs *uptr; struct user_specs *uptr;
char **old_argv = argv;
p = argv[0] + strlen (argv[0]); p = argv[0] + strlen (argv[0]);
while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
...@@ -6103,6 +6161,10 @@ main (int argc, char **argv) ...@@ -6103,6 +6161,10 @@ main (int argc, char **argv)
expandargv (&argc, &argv); expandargv (&argc, &argv);
/* Determine if any expansions were made. */
if (argv != old_argv)
at_file_supplied = true;
prune_options (&argc, &argv); prune_options (&argc, &argv);
#ifdef GCC_DRIVER_HOST_INITIALIZATION #ifdef GCC_DRIVER_HOST_INITIALIZATION
......
2007-05-07 Nathan Froyd <froydnj@codesourcery.com>
* libiberty.h (writeargv): Declare.
2007-04-25 Mark Mitchell <mark@codesourcery.com> 2007-04-25 Mark Mitchell <mark@codesourcery.com>
* demangle.h: Change license to LGPL + exception. * demangle.h: Change license to LGPL + exception.
......
...@@ -86,6 +86,10 @@ extern char **dupargv (char **) ATTRIBUTE_MALLOC; ...@@ -86,6 +86,10 @@ extern char **dupargv (char **) ATTRIBUTE_MALLOC;
extern void expandargv PARAMS ((int *, char ***)); extern void expandargv PARAMS ((int *, char ***));
/* Write argv to an @-file, inserting necessary quoting. */
extern int writeargv PARAMS ((char **, FILE *));
/* Return the last component of a path name. Note that we can't use a /* Return the last component of a path name. Note that we can't use a
prototype here because the parameter is declared inconsistently prototype here because the parameter is declared inconsistently
across different systems, sometimes as "char *" and sometimes as across different systems, sometimes as "char *" and sometimes as
......
2007-05-07 Nathan Froyd <froydnj@codesourcery.com>
* argv.c (writeargv): New function.
2007-05-05 Geoffrey Keating <geoffk@apple.com> 2007-05-05 Geoffrey Keating <geoffk@apple.com>
* cp-demangle.c (d_name): Detect local-source-name. * cp-demangle.c (d_name): Detect local-source-name.
......
...@@ -290,6 +290,62 @@ char **buildargv (const char *input) ...@@ -290,6 +290,62 @@ char **buildargv (const char *input)
/* /*
@deftypefn Extension int writeargv (const char **@var{argv}, FILE *@{file})
Write each member of ARGV, handling all necessary quoting, to the file
named by FILE, separated by whitespace. Return 0 on success, non-zero
if an error occurred while writing to FILE.
@end deftypefn
*/
int
writeargv (char **argv, FILE *f)
{
int status = 0;
if (f == NULL)
return 1;
while (*argv != NULL)
{
int ret;
const char *arg = *argv;
while (*arg != EOS)
{
char c = *arg;
if (ISSPACE(c) || c == '\\' || c == '\'' || c == '"')
if (EOF == fputc ('\\', f))
{
status = 1;
goto done;
}
if (EOF == fputc (c, f))
{
status = 1;
goto done;
}
arg++;
}
if (EOF == fputc ('\n', f))
{
status = 1;
goto done;
}
argv++;
}
done:
return status;
}
/*
@deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp}) @deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
The @var{argcp} and @code{argvp} arguments are pointers to the usual The @var{argcp} and @code{argvp} arguments are pointers to the usual
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment