This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix -dM -M -o, testcases for -dD -M etc.


On Thu, May 02, 2002 at 10:28:34AM +0200, Jakub Jelinek wrote:
> Attached below. Unfortunately, for the -M tests, I had a problem
> with the dependencies, since dg-do preprocess silently adds
> -o `basename $filename .c`.i and the dependencies are not printed
> when -o is present (only prints it to stdout, ie. if dg-do preprocess
> instead of adding -o added > `basename $filename .c`.i, it would work.
> Both egcs 1.1.2 and gcc 2.95.x choke on gcc -E -M -dM file.c -o file.i
> with cpp: Output filename specified twice
> (but with gcc -E -Wp,-M -dM file.c -o file.i they print the dependencies
> into the file (unlike gcc 3.1)).
> What do you think, should I look into cpplib to print the dependencies
> with -o too (and just change XX-final into dg-final in these tests)?

Turns out I was wrong, e.g. -dD -M -o file.i works as expected, the only
thing which did not work was -dM -M -o file.i.
It fails, because the output file is fopen("file.i", "w") by
cppmain.c(do_preprocessing), then the #define lines are printed, then
output_deps does another fopen("file.i", "w), prints the dependencies into
it, fclose()s it and afterwards (when cpp_finish returns) do_preprocessing
fclose()s the file again (which looks very wrong).
It works without -o, since then stdout is used everywhere, so it is not
actually opened/closed etc. For larger input files this may e.g. mean
that the output file can be corrupted.

Below is a hackish fix (it ensures just one stream is used for the
output file, not not). Dunno what a clean solution would be, perhaps
pushing the dependency lines as tokens and let the normal machinery output
them if -MF/-MD was not given, because the application using cpplib
does not really have to use streams for writing into the output file.

2002-05-02  Jakub Jelinek  <jakub@redhat.com>

	* cppinit.c (output_deps): Add outf argument, use it instead
	of stdout if non-NULL.
	(cpp_finish): Add outf argument, pass it to output_deps.
	(init_dependency_output): Set deps_file to "", not out_fname, if
	-MF was not given.
	* cpplib.h (cpp_finish): Add outf argument.
	* cppmain.c (do_preprocessing): Adjust callers.
	* c-common.c (c_common_finish): Likewise.

	* gcc.dg/cpp/cmdlne-dM-M.c: New test.
	* gcc.dg/cpp/cmdlne-dD-M.c: New test.
	* gcc.dg/cpp/cmdlne-dN-M.c: New test.
	* gcc.dg/cpp/cmdlne-dI-M.c: New test.
	* gcc.dg/cpp/cmdlne-dI-M.h: New aux file.
	* gcc.dg/cpp/cmdlne-dD-dM.c: New test.
	* gcc.dg/cpp/cmdlne-dM-dD.c: New test.

--- gcc/cpplib.h.jj	Fri Mar 15 14:16:28 2002
+++ gcc/cpplib.h	Thu May  2 11:26:18 2002
@@ -516,7 +516,7 @@ extern void cpp_register_pragma PARAMS (
 					 const char *, const char *,
 					 void (*) PARAMS ((cpp_reader *))));
 
-extern void cpp_finish PARAMS ((cpp_reader *));
+extern void cpp_finish PARAMS ((cpp_reader *, FILE *));
 extern int cpp_avoid_paste PARAMS ((cpp_reader *, const cpp_token *,
 				    const cpp_token *));
 extern const cpp_token *cpp_get_token PARAMS ((cpp_reader *));
--- gcc/cppmain.c.jj	Fri Mar 15 14:16:28 2002
+++ gcc/cppmain.c	Thu May  2 11:39:24 2002
@@ -173,7 +173,7 @@ do_preprocessing (argc, argv)
       if (options->dump_macros == dump_only)
 	cpp_forall_identifiers (pfile, dump_macro, NULL);
 
-      cpp_finish (pfile);
+      cpp_finish (pfile, print.outf);
     }
 
   /* Flush any pending output.  */
--- gcc/c-common.c.jj	Sun Apr 28 23:20:00 2002
+++ gcc/c-common.c	Thu May  2 11:27:16 2002
@@ -4184,7 +4184,7 @@ c_common_init (filename)
 void
 c_common_finish ()
 {
-  cpp_finish (parse_in);
+  cpp_finish (parse_in, NULL);
 
   /* For performance, avoid tearing down cpplib's internal structures.
      Call cpp_errors () instead of cpp_destroy ().  */
--- gcc/cppinit.c.jj	Wed May  1 12:31:41 2002
+++ gcc/cppinit.c	Thu May  2 11:42:27 2002
@@ -116,7 +116,7 @@ static void read_original_filename	PARAM
 static void new_pending_directive	PARAMS ((struct cpp_pending *,
 						 const char *,
 						 cl_directive_handler));
-static void output_deps			PARAMS ((cpp_reader *));
+static void output_deps			PARAMS ((cpp_reader *, FILE *));
 static int parse_option			PARAMS ((const char *));
 
 /* Fourth argument to append_include_chain: chain to use.
@@ -1076,16 +1076,19 @@ _cpp_push_next_buffer (pfile)
 
 /* Use mkdeps.c to output dependency information.  */
 static void
-output_deps (pfile)
+output_deps (pfile, outf)
      cpp_reader *pfile;
+     FILE *outf;
 {
   /* Stream on which to print the dependency information.  */
   FILE *deps_stream = 0;
   const char *const deps_mode =
     CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
 
+  if (outf == NULL)
+    outf = stdout;
   if (CPP_OPTION (pfile, deps_file)[0] == '\0')
-    deps_stream = stdout;
+    deps_stream = outf;
   else
     {
       deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode);
@@ -1102,7 +1105,7 @@ output_deps (pfile)
     deps_phony_targets (pfile->deps, deps_stream);
 
   /* Don't close stdout.  */
-  if (deps_stream != stdout)
+  if (deps_stream != outf)
     {
       if (ferror (deps_stream) || fclose (deps_stream) != 0)
 	cpp_fatal (pfile, "I/O error on output");
@@ -1114,8 +1117,9 @@ output_deps (pfile)
    clear macro definitions, such that you could call cpp_start_read
    with a new filename to restart processing.  */
 void
-cpp_finish (pfile)
+cpp_finish (pfile, outf)
      cpp_reader *pfile;
+     FILE *outf;
 {
   /* cpplex.c leaves the final buffer on the stack.  This it so that
      it returns an unending stream of CPP_EOFs to the client.  If we
@@ -1127,7 +1131,7 @@ cpp_finish (pfile)
 
   /* Don't write the deps file if preprocessing has failed.  */
   if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0)
-    output_deps (pfile);
+    output_deps (pfile, outf);
 
   /* Report on headers that could use multiple include guards.  */
   if (CPP_OPTION (pfile, print_include_names))
@@ -1897,8 +1901,8 @@ init_dependency_output (pfile)
     }
   else if (CPP_OPTION (pfile, deps_file) == 0)
     /* If -M or -MM was seen without -MF, default output to wherever
-       was specified with -o.  out_fname is non-NULL here.  */
-    CPP_OPTION (pfile, deps_file) = CPP_OPTION (pfile, out_fname);
+       was specified with -o.  */
+    CPP_OPTION (pfile, deps_file) = "";
 }
 
 /* Handle --help output.  */
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dD-M.c.jj	Thu May  2 09:53:58 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dD-M.c	Thu May  2 10:45:31 2002
@@ -0,0 +1,17 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.  */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dD -M" } */
+
+/* Test -dD -M does not fail.  It should print just
+   the Makefile rule with dependencies.  */
+
+#define foo bar
+#define funlike(like) fun like
+int variable;
+
+/* { dg-final { if ![file exists cmdlne-dD-M.i] { return }                } }
+   { dg-final { if { [grep cmdlne-dD-M.i "^#define foo bar$"] != "" } { fail "cmdlne-dD-M.c: #define line printed" } } }
+   { dg-final { if { [grep cmdlne-dD-M.i "variable"] != "" } { fail "cmdlne-dD-M.c: non-#define line printed" } } }
+   { dg-final { if { [grep cmdlne-dD-M.i "^cmdlne-dD-M.*:.*cmdlne-dD-M.c"] == "" } { fail "cmdlne-dD-M.c: dependency rule not printed" } } }
+   { dg-final { return } }  */
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dM-M.c.jj	Thu May  2 09:53:58 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dM-M.c	Thu May  2 10:47:13 2002
@@ -0,0 +1,17 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.  */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dM -M" } */
+
+/* Test -dM -M does not fail.  It should print both the
+   #define lines and a Makefile rule with dependencies.  */
+
+#define foo bar
+#define funlike(like) fun like
+int variable;
+
+/* { dg-final { if ![file exists cmdlne-dM-M.i] { return }                } }
+   { dg-final { if { [grep cmdlne-dM-M.i "^#define foo bar$"] == "" } { fail "cmdlne-dM-M.c: #define line not printed" } } }
+   { dg-final { if { [grep cmdlne-dM-M.i "variable"] != "" } { fail "cmdlne-dM-M.c: non-#define line printed" } } }
+   { dg-final { if { [grep cmdlne-dM-M.i "^cmdlne-dM-M.*:.*cmdlne-dM-M.c"] == "" } { fail "cmdlne-dM-M.c: dependency rule not printed" } } }
+   { dg-final { return } }  */
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dN-M.c.jj	Thu May  2 09:53:58 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dN-M.c	Thu May  2 10:45:15 2002
@@ -0,0 +1,17 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.  */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dN -M" } */
+
+/* Test -dN -M does not fail.  It should print just
+   the Makefile rule with dependencies.  */
+
+#define foo bar
+#define funlike(like) fun like
+int variable;
+
+/* { dg-final { if ![file exists cmdlne-dN-M.i] { return }                } }
+   { dg-final { if { [grep cmdlne-dN-M.i "^#define foo"] != "" } { fail "cmdlne-dN-M.c: #define line printed" } } }
+   { dg-final { if { [grep cmdlne-dN-M.i "variable"] != "" } { fail "cmdlne-dN-M.c: non-#define line printed" } } }
+   { dg-final { if { [grep cmdlne-dN-M.i "^cmdlne-dN-M.*:.*cmdlne-dN-M.c"] == "" } { fail "cmdlne-dN-M.c: dependency rule not printed" } } }
+   { dg-final { return } }  */
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dD-dM.c.jj	Thu May  2 09:53:58 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dD-dM.c	Thu May  2 10:22:39 2002
@@ -0,0 +1,16 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.  */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dD -dM" } */
+
+/* Test -dD -dM does not fail.  It should give the same output
+   as plain -dM.  */
+
+#define foo bar
+#define funlike(like) fun like
+int variable;
+
+/* { dg-final { if ![file exists cmdlne-dD-dM.i] { return }                } }
+   { dg-final { if { [grep cmdlne-dD-dM.i "^#define foo bar$"] == "" } { fail "cmdlne-dD-dM.c: #define line not printed" } } }
+   { dg-final { if { [grep cmdlne-dD-dM.i "variable"] != "" } { fail "cmdlne-dD-dM.c: non-#define line printed" } } }
+   { dg-final { return } }  */
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dI-M.c.jj	Thu May  2 09:53:58 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dI-M.c	Thu May  2 10:45:45 2002
@@ -0,0 +1,18 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.  */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dI -M" } */
+
+/* Test -dI -M does not fail.  It should print just
+   the Makefile rule with dependencies.  */
+
+#define foo bar
+#include "cmdlne-dI-M.h"
+#define funlike(like) fun like
+int variable;
+
+/* { dg-final { if ![file exists cmdlne-dI-M.i] { return }                } }
+   { dg-final { if { [grep cmdlne-dI-M.i "^#define foo bar$"] != "" } { fail "cmdlne-dI-M.c: #define line printed" } } }
+   { dg-final { if { [grep cmdlne-dI-M.i "variable"] != "" } { fail "cmdlne-dI-M.c: non-#define line printed" } } }
+   { dg-final { if { [grep cmdlne-dI-M.i "^cmdlne-dI-M.*:.*cmdlne-dI-M.c"] == "" } { fail "cmdlne-dI-M.c: dependency rule not printed" } } }
+   { dg-final { return } }  */
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dI-M.h.jj	Thu May  2 09:58:25 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dI-M.h	Thu May  2 10:07:11 2002
@@ -0,0 +1,2 @@
+#define baz baz
+int othervar;
--- gcc/testsuite/gcc.dg/cpp/cmdlne-dM-dD.c.jj	Thu May  2 09:53:58 2002
+++ gcc/testsuite/gcc.dg/cpp/cmdlne-dM-dD.c	Thu May  2 10:23:09 2002
@@ -0,0 +1,16 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.  */
+
+/* { dg-do preprocess } */
+/* { dg-options "-dM -dD" } */
+
+/* Test -dM -dD does not fail.  It should give the same output
+   as plain -dD.  */
+
+#define foo bar
+#define funlike(like) fun like
+int variable;
+
+/* { dg-final { if ![file exists cmdlne-dM-dD.i] { return }                } }
+   { dg-final { if { [grep cmdlne-dM-dD.i "^#define foo bar$"] == "" } { fail "cmdlne-dM-dD.c: #define line not printed" } } }
+   { dg-final { if { [grep cmdlne-dM-dD.i "variable"] == "" } { fail "cmdlne-dM-dD.c: non-#define line not printed" } } }
+   { dg-final { return } }  */


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]