gfortran supports "?" and "=?" as input with namelists (a somewhat
common vendor extension). Either of those can be used with stdin to
print the available fields of the namelist. With non-stdin input, the ?
and =? lines are simply ignored.
However, two patches, one in 2008 and one in 2011 broke that feature.
The first one broke the output of the namelist with stdin, the second
caused that the namelist read is aborted (with iostat == 0) - and the
namelist ist not read.
The attached patch fixes this. GCC 4.6 to 4.9 are affected by the latter
issue (for which the PR has been filled). The other issue affects 4.5 to
4.9 and only applies to stdin input, for which no output is shown when
using "?".
Build and regtested on x86-64-gnu-linux.
OK for the trunk - and for GCC 4.6 to 4.8?
Tobias
2013-03-28 Tobias Burnus <bur...@net-b.de>
PR fortran/56735
* io/list_read.c (nml_query): Only abort when
an error occured.
(namelist_read): Add goto instead of falling through.
2013-03-28 Tobias Burnus <bur...@net-b.de>
PR fortran/56735
* gfortran.dg/namelist_80.f90: New.
diff --git a/gcc/testsuite/gfortran.dg/namelist_80.f90 b/gcc/testsuite/gfortran.dg/namelist_80.f90
new file mode 100644
index 0000000..1961b11
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_80.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! PR fortran/56735
+!
+! Contributed by Adam Williams
+!
+ PROGRAM TEST
+ INTEGER int1,int2,int3
+ NAMELIST /temp/ int1,int2,int3
+
+ int1 = -1; int2 = -2; int3 = -3
+
+ OPEN (53, STATUS='scratch')
+ WRITE (53, '(a)') ' ?'
+ WRITE (53, '(a)')
+ WRITE (53, '(a)') '$temp'
+ WRITE (53, '(a)') ' int1=1'
+ WRITE (53, '(a)') ' int2=2'
+ WRITE (53, '(a)') ' int3=3'
+ WRITE (53, '(a)') '$END'
+ REWIND(53)
+
+ READ (53, temp)
+ CLOSE (53)
+
+ if (int1 /= 1 .or. int2 /= 2 .or. int3 /= 3) call abort()
+ END PROGRAM
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index ec45570..7ce727d 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -2380,11 +2380,11 @@ nml_query (st_parameter_dt *dtp, char c)
index_type len;
char * p;
#ifdef HAVE_CRLF
- static const index_type endlen = 3;
+ static const index_type endlen = 2;
static const char endl[] = "\r\n";
static const char nmlend[] = "&end\r\n";
#else
- static const index_type endlen = 2;
+ static const index_type endlen = 1;
static const char endl[] = "\n";
static const char nmlend[] = "&end\n";
#endif
@@ -2414,12 +2414,12 @@ nml_query (st_parameter_dt *dtp, char c)
/* "&namelist_name\n" */
len = dtp->namelist_name_len;
- p = write_block (dtp, len + endlen);
+ p = write_block (dtp, len - 1 + endlen);
if (!p)
goto query_return;
memcpy (p, "&", 1);
memcpy ((char*)(p + 1), dtp->namelist_name, len);
- memcpy ((char*)(p + len + 1), &endl, endlen - 1);
+ memcpy ((char*)(p + len + 1), &endl, endlen);
for (nl = dtp->u.p.ionml; nl; nl = nl->next)
{
/* " var_name\n" */
@@ -2430,14 +2430,15 @@ nml_query (st_parameter_dt *dtp, char c)
goto query_return;
memcpy (p, " ", 1);
memcpy ((char*)(p + 1), nl->var_name, len);
- memcpy ((char*)(p + len + 1), &endl, endlen - 1);
+ memcpy ((char*)(p + len + 1), &endl, endlen);
}
/* "&end\n" */
- p = write_block (dtp, endlen + 3);
+ p = write_block (dtp, endlen + 4);
+ if (!p)
goto query_return;
- memcpy (p, &nmlend, endlen + 3);
+ memcpy (p, &nmlend, endlen + 4);
}
/* Flush the stream to force immediate output. */
@@ -3072,6 +3073,7 @@ find_nml_name:
case '?':
nml_query (dtp, '?');
+ goto find_nml_name;
case EOF:
return;