This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix -dM -M -o, testcases for -dD -M etc.
- From: Jakub Jelinek <jakub at redhat dot com>
- To: zack at codesourcery dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 2 May 2002 11:45:21 +0200
- Subject: [PATCH] Fix -dM -M -o, testcases for -dD -M etc.
- References: <20020502102834.J32482@sunsite.ms.mff.cuni.cz>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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