From 159840cb8aef55bf2f4068f109ad6f987f31abeb Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Sun, 30 Oct 2005 13:48:52 +0100 Subject: re PR libfortran/20179 (cannot mix C and Fortran I/O) PR libfortran/20179 * io/unix.c (flush_if_preconnected): New function. * io/io.h: Add prototype for flush_if_preconnected. * io/transfer.c (data_transfer_init): Use flush_if_preconnected to workaround buggy mixed C-Fortran code. * gfortran.dg/mixed_io_1.f90: New test. * gfortran.dg/mixed_io_1.c: New file. From-SVN: r106017 --- gcc/testsuite/ChangeLog | 10 ++++++++++ gcc/testsuite/gfortran.dg/mixed_io_1.c | 4 ++++ gcc/testsuite/gfortran.dg/mixed_io_1.f90 | 5 +++++ libgfortran/ChangeLog | 8 ++++++++ libgfortran/io/io.h | 3 +++ libgfortran/io/transfer.c | 3 +++ libgfortran/io/unix.c | 17 +++++++++++++++++ 7 files changed, 50 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/mixed_io_1.c create mode 100644 gcc/testsuite/gfortran.dg/mixed_io_1.f90 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e76658c..802b4c6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2005-10-30 Francois-Xavier Coudert + + PR libfortran/20179 + * gfortran.dg/mixed_io_1.f90: New test. + * gfortran.dg/mixed_io_1.c: New file. + +2005-10-30 Francois-Xavier Coudert + + * gfortran.dg/malloc_free_1.f90: New test. + 2005-10-29 Hans-Peter Nilsson * gcc.dg/nested-func-4.c: Require profiling -pg. diff --git a/gcc/testsuite/gfortran.dg/mixed_io_1.c b/gcc/testsuite/gfortran.dg/mixed_io_1.c new file mode 100644 index 0000000..0f8d9cd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/mixed_io_1.c @@ -0,0 +1,4 @@ +#include +void cio_(void){ + printf("12345"); +} diff --git a/gcc/testsuite/gfortran.dg/mixed_io_1.f90 b/gcc/testsuite/gfortran.dg/mixed_io_1.f90 new file mode 100644 index 0000000..0dc985c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/mixed_io_1.f90 @@ -0,0 +1,5 @@ +! { dg-do run } +! { dg-additional-sources mixed_io_1.c } + call cio + write(*,"(A)") '6789' ! { dg-output "123456789" } + end diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 85ea740..0ea6adb 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,5 +1,13 @@ 2005-10-30 Francois-Xavier Coudert + PR libfortran/20179 + * io/unix.c (flush_if_preconnected): New function. + * io/io.h: Add prototype for flush_if_preconnected. + * io/transfer.c (data_transfer_init): Use flush_if_preconnected + to workaround buggy mixed C-Fortran code. + +2005-10-30 Francois-Xavier Coudert + * Makefile.am: Add intrinsics/malloc.c file. * Makefile.in: Regenerate. * intrinsics/malloc.c: New file, with implementations for free diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 90ee36c..53a21b7 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -505,6 +505,9 @@ internal_proto(is_seekable); extern int is_preconnected (stream *); internal_proto(is_preconnected); +extern void flush_if_preconnected (stream *); +internal_proto(flush_if_preconnected); + extern void empty_internal_buffer(stream *); internal_proto(empty_internal_buffer); diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 391885b..0e1e099 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -1379,6 +1379,9 @@ data_transfer_init (int read_flag) && current_unit->last_record == 0 && !is_preconnected(current_unit->s)) struncate(current_unit->s); + /* Bugware for badly written mixed C-Fortran I/O. */ + flush_if_preconnected(current_unit->s); + current_unit->mode = g.mode; /* Set the initial value of flags. */ diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 2026a36..0fe8c4b 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -228,6 +228,23 @@ is_preconnected (stream * s) return 0; } +/* If the stream corresponds to a preconnected unit, we flush the + corresponding C stream. This is bugware for mixed C-Fortran codes + where the C code doesn't flush I/O before returning. */ +void +flush_if_preconnected (stream * s) +{ + int fd; + + fd = ((unix_stream *) s)->fd; + if (fd == STDIN_FILENO) + fflush (stdin); + else if (fd == STDOUT_FILENO) + fflush (stdout); + else if (fd == STDERR_FILENO) + fflush (stderr); +} + /* Reset a stream after reading/writing. Assumes that the buffers have been flushed. */ -- cgit v1.1