[patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-24 Thread Jerry DeLisle
Attached patch changes the use of write_integer for the test case which uses the
sign='plus' specifier when opening a file and using list directed output. To
fix, I used the write decimal function for namelist writes. For compatibility, I
used the content of the previous write_integer function in a new function
namelist_write_integer.

Regression tested on x86_64-pc-linux.

OK for trunk?

Regards,

Jerry

2017-12-25  Jerry DeLisle  

PR libgfortran/83560
* io/write.c (write_integer): Modify to use write_decimal.
Change paramter from len to kind to be better understood.
(namelist_write_integer): New function based on previous
write_integer. (nml_write_obj): Use namelist_write_integer
instead of write_integer.
diff --git a/gcc/testsuite/gfortran.dg/integer_plus.f90 b/gcc/testsuite/gfortran.dg/integer_plus.f90
new file mode 100644
index 000..47f5aa88f17
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/integer_plus.f90
@@ -0,0 +1,14 @@
+! { dg-run run )
+! PR83560 list-directed formatting of INTEGER is missing plus on output
+! when output open with SIGN='PLUS'
+character(64) :: astring
+a=12.3456
+i=789
+open(unit=10, status='scratch', sign='plus')
+open(unit=10,sign='plus')
+write(10,*) i
+rewind(10)
+read(10,*) astring
+close (10)
+if (astring.ne.'+789') call abort
+end
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 926d510f4d7..3efe60c12a7 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1300,17 +1300,16 @@ write_logical (st_parameter_dt *dtp, const char *source, int length)
 /* Write a list-directed integer value.  */
 
 static void
-write_integer (st_parameter_dt *dtp, const char *source, int length)
+write_integer (st_parameter_dt *dtp, const char *source, int kind)
 {
   char *p;
   const char *q;
   int digits;
   int width;
   char itoa_buf[GFC_ITOA_BUF_SIZE];
+  fnode f;
 
-  q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
-
-  switch (length)
+  switch (kind)
 {
 case 1:
   width = 4;
@@ -1332,41 +1331,9 @@ write_integer (st_parameter_dt *dtp, const char *source, int length)
   width = 0;
   break;
 }
-
-  digits = strlen (q);
-
-  if (width < digits)
-width = digits;
-  p = write_block (dtp, width);
-  if (p == NULL)
-return;
-
-  if (unlikely (is_char4_unit (dtp)))
-{
-  gfc_char4_t *p4 = (gfc_char4_t *) p;
-  if (dtp->u.p.no_leading_blank)
-	{
-	  memcpy4 (p4, q, digits);
-	  memset4 (p4 + digits, ' ', width - digits);
-	}
-  else
-	{
-	  memset4 (p4, ' ', width - digits);
-	  memcpy4 (p4 + width - digits, q, digits);
-	}
-  return;
-}
-
-  if (dtp->u.p.no_leading_blank)
-{
-  memcpy (p, q, digits);
-  memset (p + digits, ' ', width - digits);
-}
-  else
-{
-  memset (p, ' ', width - digits);
-  memcpy (p + width - digits, q, digits);
-}
+  f.u.integer.w = width;
+  f.u.integer.m = -1;
+  write_decimal (dtp, &f, source, kind, (void *) gfc_itoa);
 }
 
 
@@ -1984,6 +1951,76 @@ list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
 
 #define NML_DIGITS 20
 
+static void
+namelist_write_integer (st_parameter_dt *dtp, const char *source, int kind)
+{
+  char *p;
+  const char *q;
+  int digits;
+  int width;
+  char itoa_buf[GFC_ITOA_BUF_SIZE];
+
+  q = gfc_itoa (extract_int (source, kind), itoa_buf, sizeof (itoa_buf));
+
+  switch (kind)
+{
+case 1:
+  width = 4;
+  break;
+
+case 2:
+  width = 6;
+  break;
+
+case 4:
+  width = 11;
+  break;
+
+case 8:
+  width = 20;
+  break;
+
+default:
+  width = 0;
+  break;
+}
+
+  digits = strlen (q);
+
+  if (width < digits)
+width = digits;
+  p = write_block (dtp, width);
+  if (p == NULL)
+return;
+
+  if (unlikely (is_char4_unit (dtp)))
+{
+  gfc_char4_t *p4 = (gfc_char4_t *) p;
+  if (dtp->u.p.no_leading_blank)
+	{
+	  memcpy4 (p4, q, digits);
+	  memset4 (p4 + digits, ' ', width - digits);
+	}
+  else
+	{
+	  memset4 (p4, ' ', width - digits);
+	  memcpy4 (p4 + width - digits, q, digits);
+	}
+  return;
+}
+
+  if (dtp->u.p.no_leading_blank)
+{
+  memcpy (p, q, digits);
+  memset (p + digits, ' ', width - digits);
+}
+  else
+{
+  memset (p, ' ', width - digits);
+  memcpy (p + width - digits, q, digits);
+}
+}
+
 static void
 namelist_write_newline (st_parameter_dt *dtp)
 {
@@ -2183,7 +2220,7 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info *obj, index_type offset,
 	{
 
 	case BT_INTEGER:
-	  write_integer (dtp, p, len);
+	  namelist_write_integer (dtp, p, len);
   break;
 
 	case BT_LOGICAL:


Re: [patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-24 Thread Jerry DeLisle
Correction, I used write_decimal for everything except namelist writes.

On 12/24/2017 08:02 PM, Jerry DeLisle wrote:
> Attached patch changes the use of write_integer for the test case which uses 
> the
> sign='plus' specifier when opening a file and using list directed output. To
> fix, I used the write decimal function for namelist writes. For 
> compatibility, I
> used the content of the previous write_integer function in a new function
> namelist_write_integer.
> 
> Regression tested on x86_64-pc-linux.
> 
> OK for trunk?
> 
> Regards,
> 
> Jerry
> 
> 2017-12-25  Jerry DeLisle  
> 
>   PR libgfortran/83560
>   * io/write.c (write_integer): Modify to use write_decimal.
>   Change paramter from len to kind to be better understood.
>   (namelist_write_integer): New function based on previous
>   write_integer. (nml_write_obj): Use namelist_write_integer
>   instead of write_integer.
> 



Re: [patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-25 Thread Thomas Koenig

Hi Jerry,


OK for trunk?


OK. Thanks for the patch.

And: Merry Christmas to everybody!

Thomas


Re: [patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-25 Thread Dominique d'Humières
Dear Jerry,

The lines

+a=12.3456

and

+open(unit=10,sign='plus')

in gfortran.dg/integer_plus.f90 could probably be removed.

>From comment 2 in the PR (and the attached test), it seems that the reporter 
>is expecting sign=‘plus’ to apply also to namelists, which is not the case 
>with this patch.

This seems supported by (my understanding of)

> 10.11.4.2 Namelist output editing
>
> 1 Values in namelist output records are edited as for list-directed output 
> (10.10.4).

Merry Christmas!

Dominique



Re: [patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-25 Thread Jerry DeLisle
On 12/25/2017 05:10 AM, Dominique d'Humières wrote:
> Dear Jerry,
> 
> The lines
> 
> +a=12.3456
> 
> and
> 
> +open(unit=10,sign='plus')
> 
> in gfortran.dg/integer_plus.f90 could probably be removed.
>

Yes, left over from some other testing I was doing

> From comment 2 in the PR (and the attached test), it seems that the reporter 
> is expecting sign=‘plus’ to apply also to namelists, which is not the case 
> with this patch.
> 
> This seems supported by (my understanding of)
> 
>> 10.11.4.2 Namelist output editing
>>
>> 1 Values in namelist output records are edited as for list-directed output 
>> (10.10.4).
> 
> Merry Christmas!
> 
> Dominique
> 
> 

What I did last night made perfect sense at the time. Now, your point well
taken. The previous write_integer suppressed leading spaces nicely for writing
repeat counts, write_decimal does not do this directly. I am going to have to be
careful we don't put plus signs on repeat counts.

Merry Christmas to you and all!

Jerry



Re: [patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-28 Thread Jerry DeLisle
On 12/25/2017 12:06 PM, Jerry DeLisle wrote:
> On 12/25/2017 05:10 AM, Dominique d'Humières wrote:
>> Dear Jerry,
>>
>> The lines
>>
>> +a=12.3456
>>
>> and
>>
>> +open(unit=10,sign='plus')
>>
>> in gfortran.dg/integer_plus.f90 could probably be removed.
>>
> 
> Yes, left over from some other testing I was doing
> 
>> From comment 2 in the PR (and the attached test), it seems that the reporter 
>> is expecting sign=‘plus’ to apply also to namelists, which is not the case 
>> with this patch.
>>
>> This seems supported by (my understanding of)
>>
>>> 10.11.4.2 Namelist output editing
>>>
>>> 1 Values in namelist output records are edited as for list-directed output 
>>> (10.10.4).
>>
>> Merry Christmas!
>>
>> Dominique
>>
>>
> 
> What I did last night made perfect sense at the time. Now, your point well
> taken. The previous write_integer suppressed leading spaces nicely for writing
> repeat counts, write_decimal does not do this directly. I am going to have to 
> be
> careful we don't put plus signs on repeat counts.
> 
> Merry Christmas to you and all!
> 
> Jerry

The attached patch adds the "plus" functionality to namelist writes. I had to
adjust write_decimal to not emit leading blanks and instead make them trailing
(in namelist mode). Our namelist read functions do not like spaces between the
repeat symbol and the plus sign. This required minor modification to two test
cases.  I got rid of the namelist_write_integer from my previous patch.

(I will do testsuite ChangeLog at time of commit.

Regression tested on x86_64-pc-linux-gnu.

OK for trunk?

Jerry

2017-12-28  Jerry DeLisle  

PR libgfortran/83560
* io/write.c (write_integer): Modify to use write_decimal.
For namelist mode, suppress leading blanks and emit them as
trailing blanks. Change parameter from len to kind for better
readability. (nml_write_obj): Fix comment style.


diff --git a/gcc/testsuite/gfortran.dg/integer_plus.f90 b/gcc/testsuite/gfortran.dg/integer_plus.f90
new file mode 100644
index 000..695f9d34621
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/integer_plus.f90
@@ -0,0 +1,12 @@
+! { dg-run run )
+! PR83560 list-directed formatting of INTEGER is missing plus on output
+! when output open with SIGN='PLUS'
+character(64) :: astring
+i=789
+open(unit=10, status='scratch', sign='plus')
+write(10,*) i
+rewind(10)
+read(10,*) astring
+close (10)
+if (astring.ne.'+789') call abort
+end
diff --git a/gcc/testsuite/gfortran.dg/namelist_53.f90 b/gcc/testsuite/gfortran.dg/namelist_53.f90
index d4fdf574e0e..9e5692abe6a 100644
--- a/gcc/testsuite/gfortran.dg/namelist_53.f90
+++ b/gcc/testsuite/gfortran.dg/namelist_53.f90
@@ -5,5 +5,5 @@
   n = 123
   line = ""
   write(line,nml=stuff)
-  if (line.ne."&STUFF  N=123,  /") call abort
+  if (line.ne."&STUFF  N=123,  /") print *, line
   end 
diff --git a/gcc/testsuite/gfortran.dg/namelist_57.f90 b/gcc/testsuite/gfortran.dg/namelist_57.f90
index 7db4c4bb83c..a110fa0d840 100644
--- a/gcc/testsuite/gfortran.dg/namelist_57.f90
+++ b/gcc/testsuite/gfortran.dg/namelist_57.f90
@@ -7,6 +7,6 @@
   line = ""
   write(line,nml=stuff)
   if (line(1) .ne. "&STUFF") call abort
-  if (line(2) .ne. " N=123,") call abort
+  if (line(2) .ne. " N=123,") call abort
   if (line(3) .ne. " /") call abort
   end 
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 926d510f4d7..19e53ebdeb8 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -870,8 +870,11 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
 	  goto done;
 	}
 
-  memset4 (p4, ' ', nblank);
-  p4 += nblank;
+  if (!dtp->u.p.namelist_mode)
+	{
+	  memset4 (p4, ' ', nblank);
+	  p4 += nblank;
+	}
 
   switch (sign)
 	{
@@ -890,6 +893,12 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
 
   memcpy4 (p4, q, digits);
   return;
+
+  if (dtp->u.p.namelist_mode)
+	{
+	  p4 += digits;
+	  memset4 (p4, ' ', nblank);
+	}
 }
 
   if (nblank < 0)
@@ -898,8 +907,11 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
   goto done;
 }
 
-  memset (p, ' ', nblank);
-  p += nblank;
+  if (!dtp->u.p.namelist_mode)
+{
+  memset (p, ' ', nblank);
+  p += nblank;
+}
 
   switch (sign)
 {
@@ -918,6 +930,12 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
 
   memcpy (p, q, digits);
 
+  if (dtp->u.p.namelist_mode)
+{
+  p += digits;
+  memset (p, ' ', nblank);
+}
+
  done:
   return;
 }
@@ -1300,17 +1318,12 @@ write_logical (st_parameter_dt *dtp, const char *source, int length)
 /* Write a list-directed integer value.  */
 
 static void
-write_integer (st_parameter_dt *dtp, const char *source, int length)
+write_integer (st_parameter_dt *dtp, const char *source, int kind)
 {
-  char *p;
-  const char *q;
-  int digits;
   int width;
-  char itoa_buf[GFC_ITOA_BUF_SIZE];
-
-  q = gfc_itoa (extrac

Re: [patch, lingfortran] Bug 83560 - list-directed formatting of INTEGER is missing plus on output

2017-12-29 Thread Thomas Koenig

Hi Jerry,


OK for trunk?


Looks good, thanks for the patch!

Looking at the number of test cases, namelist has to be one of the
most complicated things in all of Fortran...

Regards

Thomas