This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Replace system() with tlink_execute() in tlink.c
On Tue, 24 Aug 2004 11:42:37 -0700, Zack Weinberg <zack@codesourcery.com> said:
> This is on the right track, but as presently coded, it changes the
> tlink process's working directory and doesn't put it back afterward.
> I *think* you can just call getcwd early in main(), and then chdir
> back after calling tlink_execute.
Thanks for the comment. I updated the patch. I actually ended up
calling getpwd() in tlink_init(). But I think this should be fine
too.
The patch also contains the testcase now. It passes assuming that my
other patch is applied to fix extract_string() in repo.c.
The patch was regression-tested on i686-pc-linux-gnu.
Is this OK to apply?
Adam
gcc/:
2004-08-24 Adam Nemet <anemet@lnxw.com>
* tlink.c (initial_cwd): New variable.
(tlink_init): Initialize it.
(recompile_files): Use tlink_execute() instead of system(). Don't
duplicate verbose output of collect_execute. Restore initial_cwd.
Update comment before the function.
testsuite/:
2004-08-24 Adam Nemet <anemet@lnxw.com>
* g++.dg/template/repo3.C: New test.
Index: tlink.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tlink.c,v
retrieving revision 1.56
diff -u -p -r1.56 tlink.c
--- tlink.c 29 Jul 2004 17:59:24 -0000 1.56
+++ tlink.c 25 Aug 2004 01:43:26 -0000
@@ -38,6 +38,8 @@ Software Foundation, 59 Temple Place - S
extern int prepends_underscore;
static int tlink_verbose;
+
+static const char *initial_cwd;
/* Hash table boilerplate for working with htab_t. We have hash tables
for symbol names, file names, and demangled symbols. */
@@ -272,6 +274,8 @@ tlink_init (void)
if (debug)
tlink_verbose = 3;
}
+
+ initial_cwd = getpwd ();
}
static int
@@ -432,9 +436,7 @@ maybe_tweak (char *line, file *f)
}
/* Update the repo files for each of the object files we have adjusted and
- recompile.
-
- XXX Should this use collect_execute instead of system? */
+ recompile. */
static int
recompile_files (void)
@@ -446,7 +448,10 @@ recompile_files (void)
while ((f = file_pop ()) != NULL)
{
- char *line, *command;
+ char *line;
+ const char *p, *q;
+ char **argv;
+ struct obstack arg_stack;
FILE *stream = fopen (f->key, "r");
const char *const outname = frob_extension (f->key, ".rnw");
FILE *output = fopen (outname, "w");
@@ -465,31 +470,68 @@ recompile_files (void)
fclose (output);
rename (outname, f->key);
- obstack_grow (&temporary_obstack, "cd ", 3);
- obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
- obstack_grow (&temporary_obstack, "; ", 2);
- obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name));
- obstack_1grow (&temporary_obstack, ' ');
if (!f->args)
{
error ("repository file `%s' does not contain command-line "
"arguments", f->key);
return 0;
}
- obstack_grow (&temporary_obstack, f->args, strlen (f->args));
- obstack_1grow (&temporary_obstack, ' ');
- command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main));
+
+ /* Build a null-terminated argv array suitable for
+ tlink_execute(). Manipulate arguments on the arg_stack while
+ building argv on the temporary_obstack. */
+
+ obstack_init (&arg_stack);
+ obstack_ptr_grow (&temporary_obstack, c_file_name);
+
+ for (p = f->args; *p != '\0'; p = q + 1)
+ {
+ /* Arguments are delimited by single-quotes. Find the
+ opening quote. */
+ p = strchr (p, '\'');
+ if (!p)
+ goto done;
+
+ /* Find the closing quote. */
+ q = strchr (p + 1, '\'');
+ if (!q)
+ goto done;
+
+ obstack_grow (&arg_stack, p + 1, q - (p + 1));
+
+ /* Replace '\'' with '. This is how set_collect_gcc_options
+ encodes a single-quote. */
+ while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'')
+ {
+ const char *r;
+
+ r = strchr (q + 4, '\'');
+ if (!r)
+ goto done;
+
+ obstack_grow (&arg_stack, q + 3, r - (q + 3));
+ q = r;
+ }
+
+ obstack_1grow (&arg_stack, '\0');
+ obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack));
+ }
+ done:
+ obstack_ptr_grow (&temporary_obstack, f->main);
+ obstack_ptr_grow (&temporary_obstack, NULL);
+ argv = obstack_finish (&temporary_obstack);
if (tlink_verbose)
fprintf (stderr, _("collect: recompiling %s\n"), f->main);
- if (tlink_verbose >= 3)
- fprintf (stderr, "%s\n", command);
- if (system (command) != 0)
+ if (chdir (f->dir) != 0
+ || tlink_execute (c_file_name, argv, NULL) != 0
+ || chdir (initial_cwd) != 0)
return 0;
read_repo_file (f);
+ obstack_free (&arg_stack, NULL);
obstack_free (&temporary_obstack, temporary_firstobj);
}
return 1;
Index: testsuite/g++.dg/template/repo3.C
===================================================================
RCS file: testsuite/g++.dg/template/repo3.C
diff -N testsuite/g++.dg/template/repo3.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/template/repo3.C 25 Aug 2004 01:43:26 -0000
@@ -0,0 +1,7 @@
+// { dg-options "-frepo -DF='a'" }
+
+template <typename A, typename B> void f () {}
+template <typename A, typename B> void g () { f<int,int>(); }
+int main () { g<int,int>(); }
+
+char c = F;