Patchwork [fortran] PR48976 INQUIRE with STREAM= not supported

login
register
mail settings
Submitter jerry DeLisle
Date Dec. 27, 2012, 6:35 a.m.
Message ID <50DBEC46.403@charter.net>
Download mbox | patch
Permalink /patch/208271/
State New
Headers show

Comments

jerry DeLisle - Dec. 27, 2012, 6:35 a.m.
Greetings,

The attached patch implements the missing INQUIRE(99, STREAM=str) functionality 
required by the Fortran 2008 Standard.

Regression tested on x86-64.

OK for trunk with test case from the PR?

Regards,

Jerry

2012-12-27  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR fortran/48976
	* gfortran.h (gfc_inquire struct): Add pointer for inquire stream.
	* io.c (io_tag): Add tag for inquire stream. (match_inquire_element):
	Add matcher for new tag. (gfc_resolve_inquire): Resolve new tag.
	* ioparm.def: Add new parameter for inquire stream.
	* trans-io.c (gfc_trans_inquire): Add tranlste code for inquire
	stream.

2012-12-27  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libfortran/48976
	* io/inquire.c (inquire_via_unit): Set user stream inquiry variable to
	appropriate value based on unit access method. (inquire_via_filename):
	Since filename is not associated with an open unit, set stream inquiry
	to UNKNOWN.
	* io/io.h: Define inquire stream parameters.
Tobias Burnus - Dec. 27, 2012, 11:12 a.m.
Dear Jerry,

thanks for the patch.However, I wonder about the following:

Will that be backward compatible with binaries compiled with GCC < 4.8 
or will that cause problems? I have the feeling that it is okay as the 
flag ("cf2") indicating whether "stream=" is present has still the same 
type and "iqstream" comes last in st_parameter_inquire and is only set 
if (cf2 & IOPARM_INQUIRE_HAS_STREAM).

Can confirm that there is no backward-compatibility issue? If there 
isn't, the patch is okay.

Tobias

Jerry DeLisle wrote:
> 2012-12-27  Jerry DeLisle <jvdelisle@gcc.gnu.org>
>
>     PR fortran/48976
>     * gfortran.h (gfc_inquire struct): Add pointer for inquire stream.
>     * io.c (io_tag): Add tag for inquire stream. (match_inquire_element):
>     Add matcher for new tag. (gfc_resolve_inquire): Resolve new tag.
>     * ioparm.def: Add new parameter for inquire stream.
>     * trans-io.c (gfc_trans_inquire): Add tranlste code for inquire
>     stream.
>
> 2012-12-27  Jerry DeLisle <jvdelisle@gcc.gnu.org>
>
>     PR libfortran/48976
>     * io/inquire.c (inquire_via_unit): Set user stream inquiry 
> variable to
>     appropriate value based on unit access method. 
> (inquire_via_filename):
>     Since filename is not associated with an open unit, set stream 
> inquiry
>     to UNKNOWN.
>     * io/io.h: Define inquire stream parameters.
jerry DeLisle - Dec. 27, 2012, 4:50 p.m.
On 12/27/2012 03:12 AM, Tobias Burnus wrote:
> Dear Jerry,
>
> thanks for the patch.However, I wonder about the following:
>
> Will that be backward compatible with binaries compiled with GCC < 4.8 or will
> that cause problems? I have the feeling that it is okay as the flag ("cf2")
> indicating whether "stream=" is present has still the same type and "iqstream"
> comes last in st_parameter_inquire and is only set if (cf2 &
> IOPARM_INQUIRE_HAS_STREAM).
>
> Can confirm that there is no backward-compatibility issue? If there isn't, the
> patch is okay.
>
> Tobias

The cf2 flag exists and we are using the next unused bit as defined in 
ioparm.def. No previous version of the frontend or the runtime library use or 
look at this bit so there will be no compatibility issues.

I named the stream pointer iqstream to avoid it being color highlighted. My 
editor highlights "stream" has a "C" key word.

I will change the constant parameter IOPARM_INQUIRE_HAS_STREAM to 
IOPARM_INQUIRE_HAS_IQSTREAM just for consistency so that in the future, 
maintainers will know it is related to the use of the iqstream pointer.

I will commit the patch later today and thanks for the review.

Regards,

Jerry

Patch

Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 194678)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -2008,7 +2008,8 @@  typedef struct
     *name, *access, *sequential, *direct, *form, *formatted,
     *unformatted, *recl, *nextrec, *blank, *position, *action, *read,
     *write, *readwrite, *delim, *pad, *iolength, *iomsg, *convert, *strm_pos,
-    *asynchronous, *decimal, *encoding, *pending, *round, *sign, *size, *id;
+    *asynchronous, *decimal, *encoding, *pending, *round, *sign, *size, *id,
+    *iqstream;
 
   gfc_st_label *err;
 
Index: gcc/fortran/io.c
===================================================================
--- gcc/fortran/io.c	(revision 194678)
+++ gcc/fortran/io.c	(working copy)
@@ -97,7 +97,8 @@  static const io_tag
 	tag_eor		= {"EOR", " eor =", " %l", BT_UNKNOWN},
 	tag_id		= {"ID", " id =", " %v", BT_INTEGER},
 	tag_pending	= {"PENDING", " pending =", " %v", BT_LOGICAL},
-	tag_newunit	= {"NEWUNIT", " newunit =", " %v", BT_INTEGER};
+	tag_newunit	= {"NEWUNIT", " newunit =", " %v", BT_INTEGER},
+	tag_s_iqstream	= {"STREAM", " stream =", " %v", BT_CHARACTER};
 
 static gfc_dt *current_dt;
 
@@ -3912,6 +3913,7 @@  match_inquire_element (gfc_inquire *inquire)
   RETM m = match_out_tag (&tag_strm_out, &inquire->strm_pos);
   RETM m = match_vtag (&tag_pending, &inquire->pending);
   RETM m = match_vtag (&tag_id, &inquire->id);
+  RETM m = match_vtag (&tag_s_iqstream, &inquire->iqstream);
   RETM return MATCH_NO;
 }
 
@@ -4101,6 +4103,7 @@  gfc_resolve_inquire (gfc_inquire *inquire)
   INQUIRE_RESOLVE_TAG (&tag_pending, inquire->pending);
   INQUIRE_RESOLVE_TAG (&tag_size, inquire->size);
   INQUIRE_RESOLVE_TAG (&tag_s_decimal, inquire->decimal);
+  INQUIRE_RESOLVE_TAG (&tag_s_iqstream, inquire->iqstream);
 #undef INQUIRE_RESOLVE_TAG
 
   if (gfc_reference_st_label (inquire->err, ST_LABEL_TARGET) == FAILURE)
Index: gcc/fortran/ioparm.def
===================================================================
--- gcc/fortran/ioparm.def	(revision 194678)
+++ gcc/fortran/ioparm.def	(working copy)
@@ -88,6 +88,7 @@  IOPARM (inquire, sign,		1 << 4,  char1)
 IOPARM (inquire, pending,	1 << 5,  pint4)
 IOPARM (inquire, size,		1 << 6,  pintio)
 IOPARM (inquire, id,		1 << 7,  pint4)
+IOPARM (inquire, iqstream,	1 << 8,  char1)
 IOPARM (wait,    common,	0,	 common)
 IOPARM (wait,    id,		1 << 7,  pint4)
 #ifndef IOPARM_dt_list_format
Index: gcc/fortran/trans-io.c
===================================================================
--- gcc/fortran/trans-io.c	(revision 194678)
+++ gcc/fortran/trans-io.c	(working copy)
@@ -1364,6 +1364,9 @@  gfc_trans_inquire (gfc_code * code)
   if (p->id)
     mask2 |= set_parameter_ref (&block, &post_block,var, IOPARM_inquire_id,
 				p->id);
+  if (p->iqstream)
+    mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_iqstream,
+			 p->iqstream);
 
   if (mask2)
     mask |= set_parameter_const (&block, var, IOPARM_inquire_flags2, mask2);
Index: libgfortran/io/inquire.c
===================================================================
--- libgfortran/io/inquire.c	(revision 194723)
+++ libgfortran/io/inquire.c	(working copy)
@@ -414,6 +414,27 @@  inquire_via_unit (st_parameter_inquire *iqp, gfc_u
 	      *iqp->size = ssize (u->s);
 	    }
 	}
+
+      if ((cf2 & IOPARM_INQUIRE_HAS_STREAM) != 0)
+	{
+	  if (u == NULL)
+	    p = "UNKNOWN";
+	  else
+	    switch (u->flags.access)
+	      {
+	      case ACCESS_SEQUENTIAL:
+	      case ACCESS_DIRECT:
+		p = "NO";
+		break;
+	      case ACCESS_STREAM:
+		p = "YES";
+		break;
+	      default:
+		internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
+	      }
+    
+	  cf_strcpy (iqp->iqstream, iqp->iqstream_len, p);
+	}
     }
 
   if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
@@ -659,6 +680,9 @@  inquire_via_filename (st_parameter_inquire *iqp)
 
       if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
 	*iqp->size = file_size (iqp->file, iqp->file_len);
+
+      if ((cf2 & IOPARM_INQUIRE_HAS_STREAM) != 0)
+	cf_strcpy (iqp->iqstream, iqp->iqstream_len, "UNKNOWN");
     }
 
   if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
Index: libgfortran/io/io.h
===================================================================
--- libgfortran/io/io.h	(revision 194723)
+++ libgfortran/io/io.h	(working copy)
@@ -293,6 +293,7 @@  st_parameter_filepos;
 #define IOPARM_INQUIRE_HAS_PENDING	(1 << 5)
 #define IOPARM_INQUIRE_HAS_SIZE		(1 << 6)
 #define IOPARM_INQUIRE_HAS_ID		(1 << 7)
+#define IOPARM_INQUIRE_HAS_STREAM	(1 << 8)
 
 typedef struct
 {
@@ -326,6 +327,7 @@  typedef struct
   GFC_INTEGER_4 *pending;
   GFC_IO_INT *size;
   GFC_INTEGER_4 *id;
+  CHARACTER1 (iqstream);
 }
 st_parameter_inquire;