Hi all,

The attached patch fixes this by actually implementing it.  I cleaned up some of
the code by getting rid of the tmp_delim variables and adding a "mode" to
write_character which is used to ignore delimiters when writing out variable
names and other namelist parts.

I will prepare a test case.

Regression tested on x86_64.

OK for trunk or hold for next stage?

Regards,

Jerry

2014-03-01  Jerry DeLisle  <jvdeli...@gcc.gnu>

        PR libfortran/60148
        * io/inquire.c (inquire_via_unit): In the case of
        DELIM_UNSPECIFIED set inquire return string to "NONE".
        * io/list_read.c (read_character): In the case of DELIM_NONE and
        namelists, complete the character read using the namelist
        variable length.
        * io/open.c (new_unit): Don't set delim status to none if not
        specified so that DELIM_UNSPECIFIED can be used later.
        * io/transfer.c (data_transfer_init): For namelist I/O, if the
        unit delim status is unspecified set the current status to quote.
        Otherwise, set current status to the unit status.
        * io/unit.c (get_internel_unit, init_unit): Remember to set
        flags_delim initially to DELIM_UNSPECIFIED so defaults come out
        correctly.
        * io/write.c (write_character): Add a new function argument
        "mode" to signify that raw output is to be used vs output with
        delimiters. If the mode is set to DELIM (1) proceed with
        delimiters. (list_formatted_write_scalar): Write the separator
        only if a delimiter was previously specified. Update the call to
        write_character with the mode argument given.
        (namelist_write_newline): Use the mode argument. (nml_write_obj):
        Use the mode argument. Remove use of tmp_delim. Write the
        semi-colon or comma correctly only when needed with using
        delimiters. Cleanup whitespace.
        (namelist_write): If delim is not specified in namelist I/O,
        default to using quotes. Get rid of the tmp_delim variable and
        use the new mode argument if write_character.
Index: inquire.c
===================================================================
--- inquire.c	(revision 208246)
+++ inquire.c	(working copy)
@@ -523,6 +523,7 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_u
 	switch (u->flags.delim)
 	  {
 	  case DELIM_NONE:
+	  case DELIM_UNSPECIFIED:
 	    p = "NONE";
 	    break;
 	  case DELIM_QUOTE:
Index: list_read.c
===================================================================
--- list_read.c	(revision 208246)
+++ list_read.c	(working copy)
@@ -971,10 +971,24 @@ read_character (st_parameter_dt *dtp, int length _
     default:
       if (dtp->u.p.namelist_mode)
 	{
+	  if (dtp->u.p.current_unit->delim_status == DELIM_NONE)
+	    {
+	      /* No delimiters so finish reading the string now.  */
+	      int i;
+	      push_char (dtp, c);
+	      for (i = dtp->u.p.ionml->string_length; i > 1; i--)
+		{
+		  if ((c = next_char (dtp)) == EOF)
+		    goto done_eof;
+		  push_char (dtp, c);
+		}
+	      dtp->u.p.saved_type = BT_CHARACTER;
+	      free_line (dtp);
+	      return;
+	    }
 	  unget_char (dtp, c);
 	  return;
 	}
-
       push_char (dtp, c);
       goto get_string;
     }
Index: open.c
===================================================================
--- open.c	(revision 208246)
+++ open.c	(working copy)
@@ -332,17 +332,13 @@ new_unit (st_parameter_open *opp, gfc_unit *u, uni
 
   /* Checks.  */
 
-  if (flags->delim == DELIM_UNSPECIFIED)
-    flags->delim = DELIM_NONE;
-  else
+  if (flags->delim != DELIM_UNSPECIFIED
+      && flags->form == FORM_UNFORMATTED)
     {
-      if (flags->form == FORM_UNFORMATTED)
-	{
-	  generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
-			  "DELIM parameter conflicts with UNFORMATTED form in "
-			  "OPEN statement");
-	  goto fail;
-	}
+      generate_error (&opp->common, LIBERROR_OPTION_CONFLICT,
+		      "DELIM parameter conflicts with UNFORMATTED form in "
+		      "OPEN statement");
+      goto fail;
     }
 
   if (flags->blank == BLANK_UNSPECIFIED)
Index: transfer.c
===================================================================
--- transfer.c	(revision 208246)
+++ transfer.c	(working copy)
@@ -2670,16 +2670,21 @@ data_transfer_init (st_parameter_dt *dtp, int read
 	= !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
 	  find_option (&dtp->common, dtp->delim, dtp->delim_len,
 	  delim_opt, "Bad DELIM parameter in data transfer statement");
-  
+
   if (dtp->u.p.current_unit->delim_status == DELIM_UNSPECIFIED)
-    dtp->u.p.current_unit->delim_status = dtp->u.p.current_unit->flags.delim;
+    {
+      if (ionml && dtp->u.p.current_unit->flags.delim == DELIM_UNSPECIFIED)
+	dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
+      else
+	dtp->u.p.current_unit->delim_status = dtp->u.p.current_unit->flags.delim;
+    }
 
   /* Check the pad mode.  */
   dtp->u.p.current_unit->pad_status
 	= !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
 	  find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt,
 			"Bad PAD parameter in data transfer statement");
-  
+
   if (dtp->u.p.current_unit->pad_status == PAD_UNSPECIFIED)
 	dtp->u.p.current_unit->pad_status = dtp->u.p.current_unit->flags.pad;
 
Index: unit.c
===================================================================
--- unit.c	(revision 208246)
+++ unit.c	(working copy)
@@ -464,6 +464,7 @@ get_internal_unit (st_parameter_dt *dtp)
   iunit->flags.status = STATUS_UNSPECIFIED;
   iunit->flags.sign = SIGN_SUPPRESS;
   iunit->flags.decimal = DECIMAL_POINT;
+  iunit->flags.delim = DELIM_UNSPECIFIED;
   iunit->flags.encoding = ENCODING_DEFAULT;
   iunit->flags.async = ASYNC_NO;
   iunit->flags.round = ROUND_UNSPECIFIED;
@@ -584,6 +585,7 @@ init_units (void)
       u->flags.position = POSITION_ASIS;
       u->flags.sign = SIGN_SUPPRESS;
       u->flags.decimal = DECIMAL_POINT;
+      u->flags.delim = DELIM_UNSPECIFIED;
       u->flags.encoding = ENCODING_DEFAULT;
       u->flags.async = ASYNC_NO;
       u->flags.round = ROUND_UNSPECIFIED;
Index: write.c
===================================================================
--- write.c	(revision 208246)
+++ write.c	(working copy)
@@ -1312,24 +1312,32 @@ write_integer (st_parameter_dt *dtp, const char *s
 /* Write a list-directed string.  We have to worry about delimiting
    the strings if the file has been opened in that mode.  */
 
+#define DELIM 1
+#define NODELIM 0
+
 static void
-write_character (st_parameter_dt *dtp, const char *source, int kind, int length)
+write_character (st_parameter_dt *dtp, const char *source, int kind, int length, int mode)
 {
   int i, extra;
   char *p, d;
 
-  switch (dtp->u.p.current_unit->delim_status)
+  if (mode)
     {
-    case DELIM_APOSTROPHE:
-      d = '\'';
-      break;
-    case DELIM_QUOTE:
-      d = '"';
-      break;
-    default:
-      d = ' ';
-      break;
+      switch (dtp->u.p.current_unit->delim_status)
+	{
+	case DELIM_APOSTROPHE:
+	  d = '\'';
+	  break;
+	case DELIM_QUOTE:
+	  d = '"';
+	  break;
+	default:
+	  d = ' ';
+	  break;
+	}
     }
+  else
+    d = ' ';
 
   if (kind == 1)
     {
@@ -1551,7 +1559,8 @@ list_formatted_write_scalar (st_parameter_dt *dtp,
   else
     {
       if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
-	dtp->u.p.current_unit->delim_status != DELIM_NONE)
+	  (dtp->u.p.current_unit->delim_status != DELIM_NONE
+	   && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
       write_separator (dtp);
     }
 
@@ -1564,7 +1573,7 @@ list_formatted_write_scalar (st_parameter_dt *dtp,
       write_logical (dtp, p, kind);
       break;
     case BT_CHARACTER:
-      write_character (dtp, p, kind, size);
+      write_character (dtp, p, kind, size, DELIM);
       break;
     case BT_REAL:
       write_real (dtp, p, kind);
@@ -1628,9 +1637,9 @@ namelist_write_newline (st_parameter_dt *dtp)
   if (!is_internal_unit (dtp))
     {
 #ifdef HAVE_CRLF
-      write_character (dtp, "\r\n", 1, 2);
+      write_character (dtp, "\r\n", 1, 2, NODELIM);
 #else
-      write_character (dtp, "\n", 1, 1);
+      write_character (dtp, "\n", 1, 1, NODELIM);
 #endif
       return;
     }
@@ -1675,7 +1684,7 @@ namelist_write_newline (st_parameter_dt *dtp)
 	}
     }
   else
-    write_character (dtp, " ", 1, 1);
+    write_character (dtp, " ", 1, 1, NODELIM);
 }
 
 
@@ -1704,7 +1713,6 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
   size_t base_name_len;
   size_t base_var_name_len;
   size_t tot_len;
-  unit_delim tmp_delim;
   
   /* Set the character to be used to separate values
      to a comma or semi-colon.  */
@@ -1718,7 +1726,7 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
   if (obj->type != BT_DERIVED)
     {
       namelist_write_newline (dtp);
-      write_character (dtp, " ", 1, 1);
+      write_character (dtp, " ", 1, 1, NODELIM);
 
       len = 0;
       if (base)
@@ -1728,16 +1736,16 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
 	  for (dim_i = 0; dim_i < base_name_len; dim_i++)
             {
 	      cup = toupper ((int) base_name[dim_i]);
-	      write_character (dtp, &cup, 1, 1);
+	      write_character (dtp, &cup, 1, 1, NODELIM);
             }
 	}
       clen = strlen (obj->var_name);
       for (dim_i = len; dim_i < clen; dim_i++)
 	{
 	  cup = toupper ((int) obj->var_name[dim_i]);
-	  write_character (dtp, &cup, 1, 1);
+	  write_character (dtp, &cup, 1, 1, NODELIM);
 	}
-      write_character (dtp, "=", 1, 1);
+      write_character (dtp, "=", 1, 1, NODELIM);
     }
 
   /* Counts the number of data output on a line, including names.  */
@@ -1807,7 +1815,7 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
 	  if (rep_ctr > 1)
 	    {
 	      snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
-	      write_character (dtp, rep_buff, 1, strlen (rep_buff));
+	      write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
 	      dtp->u.p.no_leading_blank = 1;
 	    }
 	  num++;
@@ -1827,13 +1835,7 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
               break;
 
 	    case BT_CHARACTER:
-	      tmp_delim = dtp->u.p.current_unit->delim_status;
-	      if (dtp->u.p.nml_delim == '"')
-		dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
-	      if (dtp->u.p.nml_delim == '\'')
-		dtp->u.p.current_unit->delim_status = DELIM_APOSTROPHE;
-	      write_character (dtp, p, 1, obj->string_length);
-		dtp->u.p.current_unit->delim_status = tmp_delim;
+	      write_character (dtp, p, 1, obj->string_length, DELIM);
               break;
 
 	    case BT_REAL:
@@ -1921,12 +1923,20 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
 	     to column 2. Reset the repeat counter.  */
 
 	  dtp->u.p.no_leading_blank = 0;
-	  write_character (dtp, &semi_comma, 1, 1);
+	  if (obj->type == BT_CHARACTER)
+	    {
+	      if (dtp->u.p.nml_delim != '\0')
+		write_character (dtp, &semi_comma, 1, 1, NODELIM);
+	    }
+	  else
+	    write_character (dtp, &semi_comma, 1, 1, NODELIM);
 	  if (num > 5)
 	    {
 	      num = 0;
+	      if (dtp->u.p.nml_delim == '\0')
+		write_character (dtp, &semi_comma, 1, 1, NODELIM);
 	      namelist_write_newline (dtp);
-	      write_character (dtp, " ", 1, 1);
+	      write_character (dtp, " ", 1, 1, NODELIM);
 	    }
 	  rep_ctr = 1;
 	}
@@ -1935,17 +1945,17 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info
 
 obj_loop:
 
-    nml_carry = 1;
-    for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
-      {
-	obj->ls[dim_i].idx += nml_carry ;
-	nml_carry = 0;
- 	if (obj->ls[dim_i].idx  > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
-	  {
- 	    obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
-	    nml_carry = 1;
-	  }
-       }
+      nml_carry = 1;
+      for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
+	{
+	  obj->ls[dim_i].idx += nml_carry ;
+	  nml_carry = 0;
+	  if (obj->ls[dim_i].idx  > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
+	    {
+	      obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
+	      nml_carry = 1;
+	    }
+	 }
     }
 
   /* Return a pointer beyond the furthest object accessed.  */
@@ -1967,23 +1977,28 @@ namelist_write (st_parameter_dt *dtp)
   index_type dummy_offset = 0;
   char c;
   char * dummy_name = NULL;
-  unit_delim tmp_delim = DELIM_UNSPECIFIED;
 
   /* Set the delimiter for namelist output.  */
-  tmp_delim = dtp->u.p.current_unit->delim_status;
+  switch (dtp->u.p.current_unit->delim_status)
+    {
+      case DELIM_APOSTROPHE:
+        dtp->u.p.nml_delim = '\'';
+	break;
+      case DELIM_QUOTE:
+      case DELIM_UNSPECIFIED:
+	dtp->u.p.nml_delim = '"';
+	break;
+      default:
+	dtp->u.p.nml_delim = '\0';
+    }
 
-  dtp->u.p.nml_delim = tmp_delim == DELIM_APOSTROPHE ? '\'' : '"';
+  write_character (dtp, "&", 1, 1, NODELIM);
 
-  /* Temporarily disable namelist delimters.  */
-  dtp->u.p.current_unit->delim_status = DELIM_NONE;
-
-  write_character (dtp, "&", 1, 1);
-
   /* Write namelist name in upper case - f95 std.  */
   for (i = 0 ;i < dtp->namelist_name_len ;i++ )
     {
       c = toupper ((int) dtp->namelist_name[i]);
-      write_character (dtp, &c, 1 ,1);
+      write_character (dtp, &c, 1 ,1, NODELIM);
     }
 
   if (dtp->u.p.ionml != NULL)
@@ -1997,9 +2012,7 @@ namelist_write (st_parameter_dt *dtp)
     }
 
   namelist_write_newline (dtp);
-  write_character (dtp, " /", 1, 2);
-  /* Restore the original delimiter.  */
-  dtp->u.p.current_unit->delim_status = tmp_delim;
+  write_character (dtp, " /", 1, 2, NODELIM);
 }
 
 #undef NML_DIGITS

Reply via email to