1  /* Copyright (C) 2002-2023 Free Software Foundation, Inc.
       2     Contributed by Andy Vaught
       3     Namelist output contributed by Paul Thomas
       4     F2003 I/O support contributed by Jerry DeLisle
       5  
       6  This file is part of the GNU Fortran runtime library (libgfortran).
       7  
       8  Libgfortran is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU General Public License as published by
      10  the Free Software Foundation; either version 3, or (at your option)
      11  any later version.
      12  
      13  Libgfortran is distributed in the hope that it will be useful,
      14  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16  GNU General Public License for more details.
      17  
      18  Under Section 7 of GPL version 3, you are granted additional
      19  permissions described in the GCC Runtime Library Exception, version
      20  3.1, as published by the Free Software Foundation.
      21  
      22  You should have received a copy of the GNU General Public License and
      23  a copy of the GCC Runtime Library Exception along with this program;
      24  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      25  <http://www.gnu.org/licenses/>.  */
      26  
      27  #include "io.h"
      28  #include "fbuf.h"
      29  #include "format.h"
      30  #include "unix.h"
      31  #include <assert.h>
      32  #include <string.h>
      33  
      34  #define star_fill(p, n) memset(p, '*', n)
      35  
      36  typedef unsigned char uchar;
      37  
      38  /* Helper functions for character(kind=4) internal units.  These are needed
      39     by write_float.def.  */
      40  
      41  static void
      42  memcpy4 (gfc_char4_t *dest, const char *source, int k)
      43  {
      44    int j;
      45  
      46    const char *p = source;
      47    for (j = 0; j < k; j++)
      48      *dest++ = (gfc_char4_t) *p++;
      49  }
      50  
      51  /* This include contains the heart and soul of formatted floating point.  */
      52  #include "write_float.def"
      53  
      54  /* Write out default char4.  */
      55  
      56  static void
      57  write_default_char4 (st_parameter_dt *dtp, const gfc_char4_t *source,
      58  		     int src_len, int w_len)
      59  {
      60    char *p;
      61    int j, k = 0;
      62    gfc_char4_t c;
      63    uchar d;
      64  
      65    /* Take care of preceding blanks.  */
      66    if (w_len > src_len)
      67      {
      68        k = w_len - src_len;
      69        p = write_block (dtp, k);
      70        if (p == NULL)
      71  	return;
      72        if (is_char4_unit (dtp))
      73  	{
      74  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
      75  	  memset4 (p4, ' ', k);
      76  	}
      77        else
      78  	memset (p, ' ', k);
      79      }
      80  
      81    /* Get ready to handle delimiters if needed.  */
      82    switch (dtp->u.p.current_unit->delim_status)
      83      {
      84      case DELIM_APOSTROPHE:
      85        d = '\'';
      86        break;
      87      case DELIM_QUOTE:
      88        d = '"';
      89        break;
      90      default:
      91        d = ' ';
      92        break;
      93      }
      94  
      95    /* Now process the remaining characters, one at a time.  */
      96    for (j = 0; j < src_len; j++)
      97      {
      98        c = source[j];
      99        if (is_char4_unit (dtp))
     100  	{
     101  	  gfc_char4_t *q;
     102  	  /* Handle delimiters if any.  */
     103  	  if (c == d && d != ' ')
     104  	    {
     105  	      p = write_block (dtp, 2);
     106  	      if (p == NULL)
     107  		return;
     108  	      q = (gfc_char4_t *) p;
     109  	      *q++ = c;
     110  	    }
     111  	  else
     112  	    {
     113  	      p = write_block (dtp, 1);
     114  	      if (p == NULL)
     115  		return;
     116  	      q = (gfc_char4_t *) p;
     117  	    }
     118  	  *q = c;
     119  	}
     120        else
     121  	{
     122  	  /* Handle delimiters if any.  */
     123  	  if (c == d && d != ' ')
     124  	    {
     125  	      p = write_block (dtp, 2);
     126  	      if (p == NULL)
     127  		return;
     128  	      *p++ = (uchar) c;
     129  	    }
     130            else
     131  	    {
     132  	      p = write_block (dtp, 1);
     133  	      if (p == NULL)
     134  		return;
     135  	    }
     136  	    *p = c > 255 ? '?' : (uchar) c;
     137  	}
     138      }
     139  }
     140  
     141  
     142  /* Write out UTF-8 converted from char4.  */
     143  
     144  static void
     145  write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
     146  		     int src_len, int w_len)
     147  {
     148    char *p;
     149    int j, k = 0;
     150    gfc_char4_t c;
     151    static const uchar masks[6] =  { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
     152    static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
     153    int nbytes;
     154    uchar buf[6], d, *q;
     155  
     156    /* Take care of preceding blanks.  */
     157    if (w_len > src_len)
     158      {
     159        k = w_len - src_len;
     160        p = write_block (dtp, k);
     161        if (p == NULL)
     162  	return;
     163        memset (p, ' ', k);
     164      }
     165  
     166    /* Get ready to handle delimiters if needed.  */
     167    switch (dtp->u.p.current_unit->delim_status)
     168      {
     169      case DELIM_APOSTROPHE:
     170        d = '\'';
     171        break;
     172      case DELIM_QUOTE:
     173        d = '"';
     174        break;
     175      default:
     176        d = ' ';
     177        break;
     178      }
     179  
     180    /* Now process the remaining characters, one at a time.  */
     181    for (j = k; j < src_len; j++)
     182      {
     183        c = source[j];
     184        if (c < 0x80)
     185  	{
     186  	  /* Handle the delimiters if any.  */
     187  	  if (c == d && d != ' ')
     188  	    {
     189  	      p = write_block (dtp, 2);
     190  	      if (p == NULL)
     191  		return;
     192  	      *p++ = (uchar) c;
     193  	    }
     194  	  else
     195  	    {
     196  	      p = write_block (dtp, 1);
     197  	      if (p == NULL)
     198  		return;
     199  	    }
     200  	  *p = (uchar) c;
     201  	}
     202        else
     203  	{
     204  	  /* Convert to UTF-8 sequence.  */
     205  	  nbytes = 1;
     206  	  q = &buf[6];
     207  
     208  	  do
     209  	    {
     210  	      *--q = ((c & 0x3F) | 0x80);
     211  	      c >>= 6;
     212  	      nbytes++;
     213  	    }
     214  	  while (c >= 0x3F || (c & limits[nbytes-1]));
     215  
     216  	  *--q = (c | masks[nbytes-1]);
     217  
     218  	  p = write_block (dtp, nbytes);
     219  	  if (p == NULL)
     220  	    return;
     221  
     222  	  while (q < &buf[6])
     223  	    *p++ = *q++;
     224  	}
     225      }
     226  }
     227  
     228  
     229  /* Check the first character in source if we are using CC_FORTRAN
     230     and set the cc.type appropriately.   The cc.type is used later by write_cc
     231     to determine the output start-of-record, and next_record_cc to determine the
     232     output end-of-record.
     233     This function is called before the output buffer is allocated, so alloc_len
     234     is set to the appropriate size to allocate.  */
     235  
     236  static void
     237  write_check_cc (st_parameter_dt *dtp, const char **source, size_t *alloc_len)
     238  {
     239    /* Only valid for CARRIAGECONTROL=FORTRAN.  */
     240    if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN
     241        || alloc_len == NULL || source == NULL)
     242      return;
     243  
     244    /* Peek at the first character.  */
     245    int c = (*alloc_len > 0) ? (*source)[0] : EOF;
     246    if (c != EOF)
     247      {
     248        /* The start-of-record character which will be printed.  */
     249        dtp->u.p.cc.u.start = '\n';
     250        /* The number of characters to print at the start-of-record.
     251  	 len  > 1 means copy the SOR character multiple times.
     252  	 len == 0 means no SOR will be output.  */
     253        dtp->u.p.cc.len = 1;
     254  
     255        switch (c)
     256  	{
     257  	case '+':
     258  	  dtp->u.p.cc.type = CCF_OVERPRINT;
     259  	  dtp->u.p.cc.len = 0;
     260  	  break;
     261  	case '-':
     262  	  dtp->u.p.cc.type = CCF_ONE_LF;
     263  	  dtp->u.p.cc.len = 1;
     264  	  break;
     265  	case '0':
     266  	  dtp->u.p.cc.type = CCF_TWO_LF;
     267  	  dtp->u.p.cc.len = 2;
     268  	  break;
     269  	case '1':
     270  	  dtp->u.p.cc.type = CCF_PAGE_FEED;
     271  	  dtp->u.p.cc.len = 1;
     272  	  dtp->u.p.cc.u.start = '\f';
     273  	  break;
     274  	case '$':
     275  	  dtp->u.p.cc.type = CCF_PROMPT;
     276  	  dtp->u.p.cc.len = 1;
     277  	  break;
     278  	case '\0':
     279  	  dtp->u.p.cc.type = CCF_OVERPRINT_NOA;
     280  	  dtp->u.p.cc.len = 0;
     281  	  break;
     282  	default:
     283  	  /* In the default case we copy ONE_LF.  */
     284  	  dtp->u.p.cc.type = CCF_DEFAULT;
     285  	  dtp->u.p.cc.len = 1;
     286  	  break;
     287        }
     288  
     289        /* We add n-1 to alloc_len so our write buffer is the right size.
     290  	 We are replacing the first character, and possibly prepending some
     291  	 additional characters.  Note for n==0, we actually subtract one from
     292  	 alloc_len, which is correct, since that character is skipped.  */
     293        if (*alloc_len > 0)
     294  	{
     295  	  *source += 1;
     296  	  *alloc_len += dtp->u.p.cc.len - 1;
     297  	}
     298        /* If we have no input, there is no first character to replace.  Make
     299  	 sure we still allocate enough space for the start-of-record string.  */
     300        else
     301  	*alloc_len = dtp->u.p.cc.len;
     302      }
     303  }
     304  
     305  
     306  /* Write the start-of-record character(s) for CC_FORTRAN.
     307     Also adjusts the 'cc' struct to contain the end-of-record character
     308     for next_record_cc.
     309     The source_len is set to the remaining length to copy from the source,
     310     after the start-of-record string was inserted.  */
     311  
     312  static char *
     313  write_cc (st_parameter_dt *dtp, char *p, size_t *source_len)
     314  {
     315    /* Only valid for CARRIAGECONTROL=FORTRAN.  */
     316    if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN || source_len == NULL)
     317      return p;
     318  
     319    /* Write the start-of-record string to the output buffer.  Note that len is
     320       never more than 2.  */
     321    if (dtp->u.p.cc.len > 0)
     322      {
     323        *(p++) = dtp->u.p.cc.u.start;
     324        if (dtp->u.p.cc.len > 1)
     325  	  *(p++) = dtp->u.p.cc.u.start;
     326  
     327        /* source_len comes from write_check_cc where it is set to the full
     328  	 allocated length of the output buffer. Therefore we subtract off the
     329  	 length of the SOR string to obtain the remaining source length.  */
     330        *source_len -= dtp->u.p.cc.len;
     331      }
     332  
     333    /* Common case.  */
     334    dtp->u.p.cc.len = 1;
     335    dtp->u.p.cc.u.end = '\r';
     336  
     337    /* Update end-of-record character for next_record_w.  */
     338    switch (dtp->u.p.cc.type)
     339      {
     340      case CCF_PROMPT:
     341      case CCF_OVERPRINT_NOA:
     342        /* No end-of-record.  */
     343        dtp->u.p.cc.len = 0;
     344        dtp->u.p.cc.u.end = '\0';
     345        break;
     346      case CCF_OVERPRINT:
     347      case CCF_ONE_LF:
     348      case CCF_TWO_LF:
     349      case CCF_PAGE_FEED:
     350      case CCF_DEFAULT:
     351      default:
     352        /* Carriage return.  */
     353        dtp->u.p.cc.len = 1;
     354        dtp->u.p.cc.u.end = '\r';
     355        break;
     356      }
     357  
     358    return p;
     359  }
     360  
     361  void
     362  
     363  write_a (st_parameter_dt *dtp, const fnode *f, const char *source, size_t len)
     364  {
     365    size_t wlen;
     366    char *p;
     367  
     368    wlen = f->u.string.length < 0
     369  	 || (f->format == FMT_G && f->u.string.length == 0)
     370      ? len : (size_t) f->u.string.length;
     371  
     372  #ifdef HAVE_CRLF
     373    /* If this is formatted STREAM IO convert any embedded line feed characters
     374       to CR_LF on systems that use that sequence for newlines.  See F2003
     375       Standard sections 10.6.3 and 9.9 for further information.  */
     376    if (is_stream_io (dtp))
     377      {
     378        const char crlf[] = "\r\n";
     379        size_t q, bytes;
     380        q = bytes = 0;
     381  
     382        /* Write out any padding if needed.  */
     383        if (len < wlen)
     384  	{
     385  	  p = write_block (dtp, wlen - len);
     386  	  if (p == NULL)
     387  	    return;
     388  	  memset (p, ' ', wlen - len);
     389  	}
     390  
     391        /* Scan the source string looking for '\n' and convert it if found.  */
     392        for (size_t i = 0; i < wlen; i++)
     393  	{
     394  	  if (source[i] == '\n')
     395  	    {
     396  	      /* Write out the previously scanned characters in the string.  */
     397  	      if (bytes > 0)
     398  		{
     399  		  p = write_block (dtp, bytes);
     400  		  if (p == NULL)
     401  		    return;
     402  		  memcpy (p, &source[q], bytes);
     403  		  q += bytes;
     404  		  bytes = 0;
     405  		}
     406  
     407  	      /* Write out the CR_LF sequence.  */
     408  	      q++;
     409  	      p = write_block (dtp, 2);
     410                if (p == NULL)
     411                  return;
     412  	      memcpy (p, crlf, 2);
     413  	    }
     414  	  else
     415  	    bytes++;
     416  	}
     417  
     418        /*  Write out any remaining bytes if no LF was found.  */
     419        if (bytes > 0)
     420  	{
     421  	  p = write_block (dtp, bytes);
     422  	  if (p == NULL)
     423  	    return;
     424  	  memcpy (p, &source[q], bytes);
     425  	}
     426      }
     427    else
     428      {
     429  #endif
     430        if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
     431  	write_check_cc (dtp, &source, &wlen);
     432  
     433        p = write_block (dtp, wlen);
     434        if (p == NULL)
     435  	return;
     436  
     437        if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
     438  	p = write_cc (dtp, p, &wlen);
     439  
     440        if (unlikely (is_char4_unit (dtp)))
     441  	{
     442  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
     443  	  if (wlen < len)
     444  	    memcpy4 (p4, source, wlen);
     445  	  else
     446  	    {
     447  	      memset4 (p4, ' ', wlen - len);
     448  	      memcpy4 (p4 + wlen - len, source, len);
     449  	    }
     450  	  return;
     451  	}
     452  
     453        if (wlen < len)
     454  	memcpy (p, source, wlen);
     455        else
     456  	{
     457  	  memset (p, ' ', wlen - len);
     458  	  memcpy (p + wlen - len, source, len);
     459  	}
     460  #ifdef HAVE_CRLF
     461      }
     462  #endif
     463  }
     464  
     465  
     466  /* The primary difference between write_a_char4 and write_a is that we have to
     467     deal with writing from the first byte of the 4-byte character and pay
     468     attention to the most significant bytes.  For ENCODING="default" write the
     469     lowest significant byte. If the 3 most significant bytes contain
     470     non-zero values, emit a '?'.  For ENCODING="utf-8", convert the UCS-32 value
     471     to the UTF-8 encoded string before writing out.  */
     472  
     473  void
     474  write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, size_t len)
     475  {
     476    size_t wlen;
     477    gfc_char4_t *q;
     478  
     479    wlen = f->u.string.length < 0
     480  	 || (f->format == FMT_G && f->u.string.length == 0)
     481      ? len : (size_t) f->u.string.length;
     482  
     483    q = (gfc_char4_t *) source;
     484  #ifdef HAVE_CRLF
     485    /* If this is formatted STREAM IO convert any embedded line feed characters
     486       to CR_LF on systems that use that sequence for newlines.  See F2003
     487       Standard sections 10.6.3 and 9.9 for further information.  */
     488    if (is_stream_io (dtp))
     489      {
     490        const gfc_char4_t crlf[] = {0x000d,0x000a};
     491        size_t bytes;
     492        gfc_char4_t *qq;
     493        bytes = 0;
     494  
     495        /* Write out any padding if needed.  */
     496        if (len < wlen)
     497  	{
     498  	  char *p;
     499  	  p = write_block (dtp, wlen - len);
     500  	  if (p == NULL)
     501  	    return;
     502  	  memset (p, ' ', wlen - len);
     503  	}
     504  
     505        /* Scan the source string looking for '\n' and convert it if found.  */
     506        qq = (gfc_char4_t *) source;
     507        for (size_t i = 0; i < wlen; i++)
     508  	{
     509  	  if (qq[i] == '\n')
     510  	    {
     511  	      /* Write out the previously scanned characters in the string.  */
     512  	      if (bytes > 0)
     513  		{
     514  		  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
     515  		    write_utf8_char4 (dtp, q, bytes, 0);
     516  		  else
     517  		    write_default_char4 (dtp, q, bytes, 0);
     518  		  bytes = 0;
     519  		}
     520  
     521  	      /* Write out the CR_LF sequence.  */
     522  	      write_default_char4 (dtp, crlf, 2, 0);
     523  	    }
     524  	  else
     525  	    bytes++;
     526  	}
     527  
     528        /*  Write out any remaining bytes if no LF was found.  */
     529        if (bytes > 0)
     530  	{
     531  	  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
     532  	    write_utf8_char4 (dtp, q, bytes, 0);
     533  	  else
     534  	    write_default_char4 (dtp, q, bytes, 0);
     535  	}
     536      }
     537    else
     538      {
     539  #endif
     540        if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
     541  	write_utf8_char4 (dtp, q, len, wlen);
     542        else
     543  	write_default_char4 (dtp, q, len, wlen);
     544  #ifdef HAVE_CRLF
     545      }
     546  #endif
     547  }
     548  
     549  
     550  static GFC_INTEGER_LARGEST
     551  extract_int (const void *p, int len)
     552  {
     553    GFC_INTEGER_LARGEST i = 0;
     554  
     555    if (p == NULL)
     556      return i;
     557  
     558    switch (len)
     559      {
     560      case 1:
     561        {
     562  	GFC_INTEGER_1 tmp;
     563  	memcpy ((void *) &tmp, p, len);
     564  	i = tmp;
     565        }
     566        break;
     567      case 2:
     568        {
     569  	GFC_INTEGER_2 tmp;
     570  	memcpy ((void *) &tmp, p, len);
     571  	i = tmp;
     572        }
     573        break;
     574      case 4:
     575        {
     576  	GFC_INTEGER_4 tmp;
     577  	memcpy ((void *) &tmp, p, len);
     578  	i = tmp;
     579        }
     580        break;
     581      case 8:
     582        {
     583  	GFC_INTEGER_8 tmp;
     584  	memcpy ((void *) &tmp, p, len);
     585  	i = tmp;
     586        }
     587        break;
     588  #ifdef HAVE_GFC_INTEGER_16
     589      case 16:
     590        {
     591  	GFC_INTEGER_16 tmp;
     592  	memcpy ((void *) &tmp, p, len);
     593  	i = tmp;
     594        }
     595        break;
     596  #endif
     597      default:
     598        internal_error (NULL, "bad integer kind");
     599      }
     600  
     601    return i;
     602  }
     603  
     604  static GFC_UINTEGER_LARGEST
     605  extract_uint (const void *p, int len)
     606  {
     607    GFC_UINTEGER_LARGEST i = 0;
     608  
     609    if (p == NULL)
     610      return i;
     611  
     612    switch (len)
     613      {
     614      case 1:
     615        {
     616  	GFC_INTEGER_1 tmp;
     617  	memcpy ((void *) &tmp, p, len);
     618  	i = (GFC_UINTEGER_1) tmp;
     619        }
     620        break;
     621      case 2:
     622        {
     623  	GFC_INTEGER_2 tmp;
     624  	memcpy ((void *) &tmp, p, len);
     625  	i = (GFC_UINTEGER_2) tmp;
     626        }
     627        break;
     628      case 4:
     629        {
     630  	GFC_INTEGER_4 tmp;
     631  	memcpy ((void *) &tmp, p, len);
     632  	i = (GFC_UINTEGER_4) tmp;
     633        }
     634        break;
     635      case 8:
     636        {
     637  	GFC_INTEGER_8 tmp;
     638  	memcpy ((void *) &tmp, p, len);
     639  	i = (GFC_UINTEGER_8) tmp;
     640        }
     641        break;
     642  #ifdef HAVE_GFC_INTEGER_16
     643      case 10:
     644      case 16:
     645        {
     646  	GFC_INTEGER_16 tmp = 0;
     647  	memcpy ((void *) &tmp, p, len);
     648  	i = (GFC_UINTEGER_16) tmp;
     649        }
     650        break;
     651  # ifdef HAVE_GFC_REAL_17
     652      case 17:
     653        {
     654  	GFC_INTEGER_16 tmp = 0;
     655  	memcpy ((void *) &tmp, p, 16);
     656  	i = (GFC_UINTEGER_16) tmp;
     657        }
     658        break;
     659  # endif
     660  #endif
     661      default:
     662        internal_error (NULL, "bad integer kind");
     663      }
     664  
     665    return i;
     666  }
     667  
     668  
     669  void
     670  write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
     671  {
     672    char *p;
     673    int wlen;
     674    GFC_INTEGER_LARGEST n;
     675  
     676    wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
     677  
     678    p = write_block (dtp, wlen);
     679    if (p == NULL)
     680      return;
     681  
     682    n = extract_int (source, len);
     683  
     684    if (unlikely (is_char4_unit (dtp)))
     685      {
     686        gfc_char4_t *p4 = (gfc_char4_t *) p;
     687        memset4 (p4, ' ', wlen -1);
     688        p4[wlen - 1] = (n) ? 'T' : 'F';
     689        return;
     690      }
     691  
     692    memset (p, ' ', wlen -1);
     693    p[wlen - 1] = (n) ? 'T' : 'F';
     694  }
     695  
     696  static void
     697  write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len)
     698  {
     699    int w, m, digits, nzero, nblank;
     700    char *p;
     701  
     702    w = f->u.integer.w;
     703    m = f->u.integer.m;
     704  
     705    /* Special case:  */
     706  
     707    if (m == 0 && n == 0)
     708      {
     709        if (w == 0)
     710          w = 1;
     711  
     712        p = write_block (dtp, w);
     713        if (p == NULL)
     714          return;
     715        if (unlikely (is_char4_unit (dtp)))
     716  	{
     717  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
     718  	  memset4 (p4, ' ', w);
     719  	}
     720        else
     721  	memset (p, ' ', w);
     722        goto done;
     723      }
     724  
     725    digits = strlen (q);
     726  
     727    /* Select a width if none was specified.  The idea here is to always
     728       print something.  */
     729  
     730    if (w == DEFAULT_WIDTH)
     731      w = default_width_for_integer (len);
     732  
     733    if (w == 0)
     734      w = ((digits < m) ? m : digits);
     735  
     736    p = write_block (dtp, w);
     737    if (p == NULL)
     738      return;
     739  
     740    nzero = 0;
     741    if (digits < m)
     742      nzero = m - digits;
     743  
     744    /* See if things will work.  */
     745  
     746    nblank = w - (nzero + digits);
     747  
     748    if (unlikely (is_char4_unit (dtp)))
     749      {
     750        gfc_char4_t *p4 = (gfc_char4_t *) p;
     751        if (nblank < 0)
     752  	{
     753  	  memset4 (p4, '*', w);
     754  	  return;
     755  	}
     756  
     757        if (!dtp->u.p.no_leading_blank)
     758  	{
     759  	  memset4 (p4, ' ', nblank);
     760  	  q += nblank;
     761  	  memset4 (p4, '0', nzero);
     762  	  q += nzero;
     763  	  memcpy4 (p4, q, digits);
     764  	}
     765        else
     766  	{
     767  	  memset4 (p4, '0', nzero);
     768  	  q += nzero;
     769  	  memcpy4 (p4, q, digits);
     770  	  q += digits;
     771  	  memset4 (p4, ' ', nblank);
     772  	  dtp->u.p.no_leading_blank = 0;
     773  	}
     774        return;
     775      }
     776  
     777    if (nblank < 0)
     778      {
     779        star_fill (p, w);
     780        goto done;
     781      }
     782  
     783    if (!dtp->u.p.no_leading_blank)
     784      {
     785        memset (p, ' ', nblank);
     786        p += nblank;
     787        memset (p, '0', nzero);
     788        p += nzero;
     789        memcpy (p, q, digits);
     790      }
     791    else
     792      {
     793        memset (p, '0', nzero);
     794        p += nzero;
     795        memcpy (p, q, digits);
     796        p += digits;
     797        memset (p, ' ', nblank);
     798        dtp->u.p.no_leading_blank = 0;
     799      }
     800  
     801   done:
     802    return;
     803  }
     804  
     805  static void
     806  write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
     807  	       int len)
     808  {
     809    GFC_INTEGER_LARGEST n = 0;
     810    GFC_UINTEGER_LARGEST absn;
     811    int w, m, digits, nsign, nzero, nblank;
     812    char *p;
     813    const char *q;
     814    sign_t sign;
     815    char itoa_buf[GFC_BTOA_BUF_SIZE];
     816  
     817    w = f->u.integer.w;
     818    m = f->format == FMT_G ? -1 : f->u.integer.m;
     819  
     820    n = extract_int (source, len);
     821  
     822    /* Special case:  */
     823    if (m == 0 && n == 0)
     824      {
     825        if (w == 0)
     826          w = 1;
     827  
     828        p = write_block (dtp, w);
     829        if (p == NULL)
     830          return;
     831        if (unlikely (is_char4_unit (dtp)))
     832  	{
     833  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
     834  	  memset4 (p4, ' ', w);
     835  	}
     836        else
     837  	memset (p, ' ', w);
     838        goto done;
     839      }
     840  
     841    sign = calculate_sign (dtp, n < 0);
     842    if (n < 0)
     843      /* Use unsigned to protect from overflow. */
     844      absn = -(GFC_UINTEGER_LARGEST) n;
     845    else
     846      absn = n;
     847    nsign = sign == S_NONE ? 0 : 1;
     848  
     849    /* gfc_itoa() converts the nonnegative value to decimal representation.  */
     850    q = gfc_itoa (absn, itoa_buf, sizeof (itoa_buf));
     851    digits = strlen (q);
     852  
     853    /* Select a width if none was specified.  The idea here is to always
     854       print something.  */
     855    if (w == DEFAULT_WIDTH)
     856      w = default_width_for_integer (len);
     857  
     858    if (w == 0)
     859      w = ((digits < m) ? m : digits) + nsign;
     860  
     861    p = write_block (dtp, w);
     862    if (p == NULL)
     863      return;
     864  
     865    nzero = 0;
     866    if (digits < m)
     867      nzero = m - digits;
     868  
     869    /* See if things will work.  */
     870  
     871    nblank = w - (nsign + nzero + digits);
     872  
     873    if (unlikely (is_char4_unit (dtp)))
     874      {
     875        gfc_char4_t *p4 = (gfc_char4_t *)p;
     876        if (nblank < 0)
     877  	{
     878  	  memset4 (p4, '*', w);
     879  	  goto done;
     880  	}
     881  
     882        if (!dtp->u.p.namelist_mode)
     883  	{
     884  	  memset4 (p4, ' ', nblank);
     885  	  p4 += nblank;
     886  	}
     887  
     888        switch (sign)
     889  	{
     890  	case S_PLUS:
     891  	  *p4++ = '+';
     892  	  break;
     893  	case S_MINUS:
     894  	  *p4++ = '-';
     895  	  break;
     896  	case S_NONE:
     897  	  break;
     898  	}
     899  
     900        memset4 (p4, '0', nzero);
     901        p4 += nzero;
     902  
     903        memcpy4 (p4, q, digits);
     904        return;
     905  
     906        if (dtp->u.p.namelist_mode)
     907  	{
     908  	  p4 += digits;
     909  	  memset4 (p4, ' ', nblank);
     910  	}
     911      }
     912  
     913    if (nblank < 0)
     914      {
     915        star_fill (p, w);
     916        goto done;
     917      }
     918  
     919    if (!dtp->u.p.namelist_mode)
     920      {
     921        memset (p, ' ', nblank);
     922        p += nblank;
     923      }
     924  
     925    switch (sign)
     926      {
     927      case S_PLUS:
     928        *p++ = '+';
     929        break;
     930      case S_MINUS:
     931        *p++ = '-';
     932        break;
     933      case S_NONE:
     934        break;
     935      }
     936  
     937    memset (p, '0', nzero);
     938    p += nzero;
     939  
     940    memcpy (p, q, digits);
     941  
     942    if (dtp->u.p.namelist_mode)
     943      {
     944        p += digits;
     945        memset (p, ' ', nblank);
     946      }
     947  
     948   done:
     949    return;
     950  }
     951  
     952  
     953  /* Convert hexadecimal to ASCII.  */
     954  
     955  static const char *
     956  xtoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
     957  {
     958    int digit;
     959    char *p;
     960  
     961    assert (len >= GFC_XTOA_BUF_SIZE);
     962  
     963    if (n == 0)
     964      return "0";
     965  
     966    p = buffer + GFC_XTOA_BUF_SIZE - 1;
     967    *p = '\0';
     968  
     969    while (n != 0)
     970      {
     971        digit = n & 0xF;
     972        if (digit > 9)
     973  	digit += 'A' - '0' - 10;
     974  
     975        *--p = '0' + digit;
     976        n >>= 4;
     977      }
     978  
     979    return p;
     980  }
     981  
     982  
     983  /* Convert unsigned octal to ASCII.  */
     984  
     985  static const char *
     986  otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
     987  {
     988    char *p;
     989  
     990    assert (len >= GFC_OTOA_BUF_SIZE);
     991  
     992    if (n == 0)
     993      return "0";
     994  
     995    p = buffer + GFC_OTOA_BUF_SIZE - 1;
     996    *p = '\0';
     997  
     998    while (n != 0)
     999      {
    1000        *--p = '0' + (n & 7);
    1001        n >>= 3;
    1002      }
    1003  
    1004    return p;
    1005  }
    1006  
    1007  
    1008  /* Convert unsigned binary to ASCII.  */
    1009  
    1010  static const char *
    1011  btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
    1012  {
    1013    char *p;
    1014  
    1015    assert (len >= GFC_BTOA_BUF_SIZE);
    1016  
    1017    if (n == 0)
    1018      return "0";
    1019  
    1020    p = buffer + GFC_BTOA_BUF_SIZE - 1;
    1021    *p = '\0';
    1022  
    1023    while (n != 0)
    1024      {
    1025        *--p = '0' + (n & 1);
    1026        n >>= 1;
    1027      }
    1028  
    1029    return p;
    1030  }
    1031  
    1032  /* The following three functions, btoa_big, otoa_big, and xtoa_big, are needed
    1033     to convert large reals with kind sizes that exceed the largest integer type
    1034     available on certain platforms.  In these cases, byte by byte conversion is
    1035     performed. Endianess is taken into account.  */
    1036  
    1037  /* Conversion to binary.  */
    1038  
    1039  static const char *
    1040  btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
    1041  {
    1042    char *q;
    1043    int i, j;
    1044  
    1045    q = buffer;
    1046    if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
    1047      {
    1048        const char *p = s;
    1049        for (i = 0; i < len; i++)
    1050  	{
    1051  	  char c = *p;
    1052  
    1053  	  /* Test for zero. Needed by write_boz later.  */
    1054  	  if (*p != 0)
    1055  	    *n = 1;
    1056  
    1057  	  for (j = 0; j < 8; j++)
    1058  	    {
    1059  	      *q++ = (c & 128) ? '1' : '0';
    1060  	      c <<= 1;
    1061  	    }
    1062  	  p++;
    1063  	}
    1064      }
    1065    else
    1066      {
    1067        const char *p = s + len - 1;
    1068        for (i = 0; i < len; i++)
    1069  	{
    1070  	  char c = *p;
    1071  
    1072  	  /* Test for zero. Needed by write_boz later.  */
    1073  	  if (*p != 0)
    1074  	    *n = 1;
    1075  
    1076  	  for (j = 0; j < 8; j++)
    1077  	    {
    1078  	      *q++ = (c & 128) ? '1' : '0';
    1079  	      c <<= 1;
    1080  	    }
    1081  	  p--;
    1082  	}
    1083      }
    1084  
    1085    if (*n == 0)
    1086      return "0";
    1087  
    1088    /* Move past any leading zeros.  */
    1089    while (*buffer == '0')
    1090      buffer++;
    1091  
    1092    return buffer;
    1093  
    1094  }
    1095  
    1096  /* Conversion to octal.  */
    1097  
    1098  static const char *
    1099  otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
    1100  {
    1101    char *q;
    1102    int i, j, k;
    1103    uint8_t octet;
    1104  
    1105    q = buffer + GFC_OTOA_BUF_SIZE - 1;
    1106    *q = '\0';
    1107    i = k = octet = 0;
    1108  
    1109    if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
    1110      {
    1111        const char *p = s + len - 1;
    1112        char c = *p;
    1113        while (i < len)
    1114  	{
    1115  	  /* Test for zero. Needed by write_boz later.  */
    1116  	  if (*p != 0)
    1117  	    *n = 1;
    1118  
    1119  	  for (j = 0; j < 3 && i < len; j++)
    1120  	    {
    1121  	      octet |= (c & 1) << j;
    1122  	      c >>= 1;
    1123  	      if (++k > 7)
    1124  	        {
    1125  		  i++;
    1126  		  k = 0;
    1127  		  c = *--p;
    1128  		}
    1129  	    }
    1130  	  *--q = '0' + octet;
    1131  	  octet = 0;
    1132  	}
    1133      }
    1134    else
    1135      {
    1136        const char *p = s;
    1137        char c = *p;
    1138        while (i < len)
    1139  	{
    1140  	  /* Test for zero. Needed by write_boz later.  */
    1141  	  if (*p != 0)
    1142  	    *n = 1;
    1143  
    1144  	  for (j = 0; j < 3 && i < len; j++)
    1145  	    {
    1146  	      octet |= (c & 1) << j;
    1147  	      c >>= 1;
    1148  	      if (++k > 7)
    1149  	        {
    1150  		  i++;
    1151  		  k = 0;
    1152  		  c = *++p;
    1153  		}
    1154  	    }
    1155  	  *--q = '0' + octet;
    1156  	  octet = 0;
    1157  	}
    1158      }
    1159  
    1160    if (*n == 0)
    1161      return "0";
    1162  
    1163    /* Move past any leading zeros.  */
    1164    while (*q == '0')
    1165      q++;
    1166  
    1167    return q;
    1168  }
    1169  
    1170  /* Conversion to hexadecimal.  */
    1171  
    1172  static const char *
    1173  xtoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
    1174  {
    1175    static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
    1176      '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    1177  
    1178    char *q;
    1179    uint8_t h, l;
    1180    int i;
    1181  
    1182    q = buffer;
    1183  
    1184    if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
    1185      {
    1186        const char *p = s;
    1187        for (i = 0; i < len; i++)
    1188  	{
    1189  	  /* Test for zero. Needed by write_boz later.  */
    1190  	  if (*p != 0)
    1191  	    *n = 1;
    1192  
    1193  	  h = (*p >> 4) & 0x0F;
    1194  	  l = *p++ & 0x0F;
    1195  	  *q++ = a[h];
    1196  	  *q++ = a[l];
    1197  	}
    1198      }
    1199    else
    1200      {
    1201        const char *p = s + len - 1;
    1202        for (i = 0; i < len; i++)
    1203  	{
    1204  	  /* Test for zero. Needed by write_boz later.  */
    1205  	  if (*p != 0)
    1206  	    *n = 1;
    1207  
    1208  	  h = (*p >> 4) & 0x0F;
    1209  	  l = *p-- & 0x0F;
    1210  	  *q++ = a[h];
    1211  	  *q++ = a[l];
    1212  	}
    1213      }
    1214  
    1215    /* write_z, which calls xtoa_big, is called from transfer.c,
    1216       formatted_transfer_scalar_write.  There it is passed the kind as
    1217       argument, which means a maximum of 16.  The buffer is large
    1218       enough, but the compiler does not know that, so shut up the
    1219       warning here.  */
    1220  #pragma GCC diagnostic push
    1221  #pragma GCC diagnostic ignored "-Wstringop-overflow"
    1222    *q = '\0';
    1223  #pragma GCC diagnostic pop
    1224  
    1225    if (*n == 0)
    1226      return "0";
    1227  
    1228    /* Move past any leading zeros.  */
    1229    while (*buffer == '0')
    1230      buffer++;
    1231  
    1232    return buffer;
    1233  }
    1234  
    1235  
    1236  void
    1237  write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
    1238  {
    1239    write_decimal (dtp, f, p, len);
    1240  }
    1241  
    1242  
    1243  void
    1244  write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
    1245  {
    1246    const char *p;
    1247    char itoa_buf[GFC_BTOA_BUF_SIZE];
    1248    GFC_UINTEGER_LARGEST n = 0;
    1249  
    1250    /* Ensure we end up with a null terminated string.  */
    1251    memset(itoa_buf, '\0', GFC_BTOA_BUF_SIZE);
    1252  
    1253    if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
    1254      {
    1255        p = btoa_big (source, itoa_buf, len, &n);
    1256        write_boz (dtp, f, p, n, len);
    1257      }
    1258    else
    1259      {
    1260        n = extract_uint (source, len);
    1261        p = btoa (n, itoa_buf, sizeof (itoa_buf));
    1262        write_boz (dtp, f, p, n, len);
    1263      }
    1264  }
    1265  
    1266  
    1267  void
    1268  write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
    1269  {
    1270    const char *p;
    1271    char itoa_buf[GFC_OTOA_BUF_SIZE];
    1272    GFC_UINTEGER_LARGEST n = 0;
    1273  
    1274    if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
    1275      {
    1276        p = otoa_big (source, itoa_buf, len, &n);
    1277        write_boz (dtp, f, p, n, len);
    1278      }
    1279    else
    1280      {
    1281        n = extract_uint (source, len);
    1282        p = otoa (n, itoa_buf, sizeof (itoa_buf));
    1283        write_boz (dtp, f, p, n, len);
    1284      }
    1285  }
    1286  
    1287  void
    1288  write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
    1289  {
    1290    const char *p;
    1291    char itoa_buf[GFC_XTOA_BUF_SIZE];
    1292    GFC_UINTEGER_LARGEST n = 0;
    1293  
    1294    if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
    1295      {
    1296        p = xtoa_big (source, itoa_buf, len, &n);
    1297        write_boz (dtp, f, p, n, len);
    1298      }
    1299    else
    1300      {
    1301        n = extract_uint (source, len);
    1302        p = xtoa (n, itoa_buf, sizeof (itoa_buf));
    1303        write_boz (dtp, f, p, n, len);
    1304      }
    1305  }
    1306  
    1307  /* Take care of the X/TR descriptor.  */
    1308  
    1309  void
    1310  write_x (st_parameter_dt *dtp, int len, int nspaces)
    1311  {
    1312    char *p;
    1313  
    1314    p = write_block (dtp, len);
    1315    if (p == NULL)
    1316      return;
    1317    if (nspaces > 0 && len - nspaces >= 0)
    1318      {
    1319        if (unlikely (is_char4_unit (dtp)))
    1320  	{
    1321  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
    1322  	  memset4 (&p4[len - nspaces], ' ', nspaces);
    1323  	}
    1324        else
    1325  	memset (&p[len - nspaces], ' ', nspaces);
    1326      }
    1327  }
    1328  
    1329  
    1330  /* List-directed writing.  */
    1331  
    1332  
    1333  /* Write a single character to the output.  Returns nonzero if
    1334     something goes wrong.  */
    1335  
    1336  static int
    1337  write_char (st_parameter_dt *dtp, int c)
    1338  {
    1339    char *p;
    1340  
    1341    p = write_block (dtp, 1);
    1342    if (p == NULL)
    1343      return 1;
    1344    if (unlikely (is_char4_unit (dtp)))
    1345      {
    1346        gfc_char4_t *p4 = (gfc_char4_t *) p;
    1347        *p4 = c;
    1348        return 0;
    1349      }
    1350  
    1351    *p = (uchar) c;
    1352  
    1353    return 0;
    1354  }
    1355  
    1356  
    1357  /* Write a list-directed logical value.  */
    1358  
    1359  static void
    1360  write_logical (st_parameter_dt *dtp, const char *source, int length)
    1361  {
    1362    write_char (dtp, extract_int (source, length) ? 'T' : 'F');
    1363  }
    1364  
    1365  
    1366  /* Write a list-directed integer value.  */
    1367  
    1368  static void
    1369  write_integer (st_parameter_dt *dtp, const char *source, int kind)
    1370  {
    1371    int width;
    1372    fnode f;
    1373  
    1374    switch (kind)
    1375      {
    1376      case 1:
    1377        width = 4;
    1378        break;
    1379  
    1380      case 2:
    1381        width = 6;
    1382        break;
    1383  
    1384      case 4:
    1385        width = 11;
    1386        break;
    1387  
    1388      case 8:
    1389        width = 20;
    1390        break;
    1391  
    1392      case 16:
    1393        width = 40;
    1394        break;
    1395  
    1396      default:
    1397        width = 0;
    1398        break;
    1399      }
    1400    f.u.integer.w = width;
    1401    f.u.integer.m = -1;
    1402    f.format = FMT_NONE;
    1403    write_decimal (dtp, &f, source, kind);
    1404  }
    1405  
    1406  
    1407  /* Write a list-directed string.  We have to worry about delimiting
    1408     the strings if the file has been opened in that mode.  */
    1409  
    1410  #define DELIM 1
    1411  #define NODELIM 0
    1412  
    1413  static void
    1414  write_character (st_parameter_dt *dtp, const char *source, int kind, size_t length, int mode)
    1415  {
    1416    size_t extra;
    1417    char *p, d;
    1418  
    1419    if (mode == DELIM)
    1420      {
    1421        switch (dtp->u.p.current_unit->delim_status)
    1422  	{
    1423  	case DELIM_APOSTROPHE:
    1424  	  d = '\'';
    1425  	  break;
    1426  	case DELIM_QUOTE:
    1427  	  d = '"';
    1428  	  break;
    1429  	default:
    1430  	  d = ' ';
    1431  	  break;
    1432  	}
    1433      }
    1434    else
    1435      d = ' ';
    1436  
    1437    if (kind == 1)
    1438      {
    1439        if (d == ' ')
    1440  	extra = 0;
    1441        else
    1442  	{
    1443  	  extra = 2;
    1444  
    1445  	  for (size_t i = 0; i < length; i++)
    1446  	    if (source[i] == d)
    1447  	      extra++;
    1448  	}
    1449  
    1450        p = write_block (dtp, length + extra);
    1451        if (p == NULL)
    1452  	return;
    1453  
    1454        if (unlikely (is_char4_unit (dtp)))
    1455  	{
    1456  	  gfc_char4_t d4 = (gfc_char4_t) d;
    1457  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
    1458  
    1459  	  if (d4 == ' ')
    1460  	    memcpy4 (p4, source, length);
    1461  	  else
    1462  	    {
    1463  	      *p4++ = d4;
    1464  
    1465  	      for (size_t i = 0; i < length; i++)
    1466  		{
    1467  		  *p4++ = (gfc_char4_t) source[i];
    1468  		  if (source[i] == d)
    1469  		    *p4++ = d4;
    1470  		}
    1471  
    1472  	      *p4 = d4;
    1473  	    }
    1474  	  return;
    1475  	}
    1476  
    1477        if (d == ' ')
    1478  	memcpy (p, source, length);
    1479        else
    1480  	{
    1481  	  *p++ = d;
    1482  
    1483  	  for (size_t i = 0; i < length; i++)
    1484              {
    1485                *p++ = source[i];
    1486                if (source[i] == d)
    1487  		*p++ = d;
    1488  	    }
    1489  
    1490  	  *p = d;
    1491  	}
    1492      }
    1493    else
    1494      {
    1495        if (d == ' ')
    1496  	{
    1497  	  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
    1498  	    write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
    1499  	  else
    1500  	    write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
    1501  	}
    1502        else
    1503  	{
    1504  	  p = write_block (dtp, 1);
    1505  	  *p = d;
    1506  
    1507  	  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
    1508  	    write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
    1509  	  else
    1510  	    write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
    1511  
    1512  	  p = write_block (dtp, 1);
    1513  	  *p = d;
    1514  	}
    1515      }
    1516  }
    1517  
    1518  /* Floating point helper functions.  */
    1519  
    1520  #define BUF_STACK_SZ 384
    1521  
    1522  static int
    1523  get_precision (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
    1524  {
    1525    if (f->format != FMT_EN)
    1526      return determine_precision (dtp, f, kind);
    1527    else
    1528      return determine_en_precision (dtp, f, source, kind);
    1529  }
    1530  
    1531  /* 4932 is the maximum exponent of long double and quad precision, 3
    1532     extra characters for the sign, the decimal point, and the
    1533     trailing null.  Extra digits are added by the calling functions for
    1534     requested precision. Likewise for float and double.  F0 editing produces
    1535     full precision output.  */
    1536  static int
    1537  size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
    1538  {
    1539    int size;
    1540  
    1541    if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH)
    1542      {
    1543        switch (kind)
    1544        {
    1545  	case 4:
    1546  	  size = 38 + 3; /* These constants shown for clarity.  */
    1547  	  break;
    1548  	case 8:
    1549  	  size = 308 + 3;
    1550  	  break;
    1551  	case 10:
    1552  	  size = 4932 + 3;
    1553  	  break;
    1554  	case 16:
    1555  #ifdef HAVE_GFC_REAL_17
    1556  	case 17:
    1557  #endif
    1558  	  size = 4932 + 3;
    1559  	  break;
    1560  	default:
    1561  	  internal_error (&dtp->common, "bad real kind");
    1562  	  break;
    1563        }
    1564      }
    1565    else
    1566      size = f->u.real.w + 1; /* One byte for a NULL character.  */
    1567  
    1568    return size;
    1569  }
    1570  
    1571  static char *
    1572  select_buffer (st_parameter_dt *dtp, const fnode *f, int precision,
    1573  	       char *buf, size_t *size, int kind)
    1574  {
    1575    char *result;
    1576    
    1577    /* The buffer needs at least one more byte to allow room for
    1578       normalizing and 1 to hold null terminator.  */
    1579    *size = size_from_kind (dtp, f, kind) + precision + 1 + 1;
    1580  
    1581    if (*size > BUF_STACK_SZ)
    1582       result = xmalloc (*size);
    1583    else
    1584       result = buf;
    1585    return result;
    1586  }
    1587  
    1588  static char *
    1589  select_string (st_parameter_dt *dtp, const fnode *f, char *buf, size_t *size,
    1590  	       int kind)
    1591  {
    1592    char *result;
    1593    *size = size_from_kind (dtp, f, kind) + f->u.real.d + 1;
    1594    if (*size > BUF_STACK_SZ)
    1595       result = xmalloc (*size);
    1596    else
    1597       result = buf;
    1598    return result;
    1599  }
    1600  
    1601  static void
    1602  write_float_string (st_parameter_dt *dtp, char *fstr, size_t len)
    1603  {
    1604    char *p = write_block (dtp, len);
    1605    if (p == NULL)
    1606      return;
    1607  
    1608    if (unlikely (is_char4_unit (dtp)))
    1609      {
    1610        gfc_char4_t *p4 = (gfc_char4_t *) p;
    1611        memcpy4 (p4, fstr, len);
    1612        return;
    1613      }
    1614    memcpy (p, fstr, len);
    1615  }
    1616  
    1617  
    1618  static void
    1619  write_float_0 (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
    1620  {
    1621    char buf_stack[BUF_STACK_SZ];
    1622    char str_buf[BUF_STACK_SZ];
    1623    char *buffer, *result;
    1624    size_t buf_size, res_len, flt_str_len;
    1625  
    1626    /* Precision for snprintf call.  */
    1627    int precision = get_precision (dtp, f, source, kind);
    1628  
    1629    /* String buffer to hold final result.  */
    1630    result = select_string (dtp, f, str_buf, &res_len, kind);
    1631  
    1632    buffer = select_buffer (dtp, f, precision, buf_stack, &buf_size, kind);
    1633  
    1634    get_float_string (dtp, f, source , kind, 0, buffer,
    1635                             precision, buf_size, result, &flt_str_len);
    1636    write_float_string (dtp, result, flt_str_len);
    1637  
    1638    if (buf_size > BUF_STACK_SZ)
    1639      free (buffer);
    1640    if (res_len > BUF_STACK_SZ)
    1641      free (result);
    1642  }
    1643  
    1644  void
    1645  write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
    1646  {
    1647    write_float_0 (dtp, f, p, len);
    1648  }
    1649  
    1650  
    1651  void
    1652  write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
    1653  {
    1654    write_float_0 (dtp, f, p, len);
    1655  }
    1656  
    1657  
    1658  void
    1659  write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
    1660  {
    1661    write_float_0 (dtp, f, p, len);
    1662  }
    1663  
    1664  
    1665  void
    1666  write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
    1667  {
    1668    write_float_0 (dtp, f, p, len);
    1669  }
    1670  
    1671  
    1672  void
    1673  write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
    1674  {
    1675    write_float_0 (dtp, f, p, len);
    1676  }
    1677  
    1678  
    1679  /* Set an fnode to default format.  */
    1680  
    1681  static void
    1682  set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
    1683  {
    1684    f->format = FMT_G;
    1685    switch (length)
    1686      {
    1687      case 4:
    1688        f->u.real.w = 16;
    1689        f->u.real.d = 9;
    1690        f->u.real.e = 2;
    1691        break;
    1692      case 8:
    1693        f->u.real.w = 25;
    1694        f->u.real.d = 17;
    1695        f->u.real.e = 3;
    1696        break;
    1697      case 10:
    1698        f->u.real.w = 30;
    1699        f->u.real.d = 21;
    1700        f->u.real.e = 4;
    1701        break;
    1702      case 16:
    1703        /* Adjust decimal precision depending on binary precision, 106 or 113.  */
    1704  #if GFC_REAL_16_DIGITS == 113
    1705        f->u.real.w = 45;
    1706        f->u.real.d = 36;
    1707        f->u.real.e = 4;
    1708  #else
    1709        f->u.real.w = 41;
    1710        f->u.real.d = 32;
    1711        f->u.real.e = 4;
    1712  #endif
    1713        break;
    1714  #ifdef HAVE_GFC_REAL_17
    1715      case 17:
    1716        f->u.real.w = 45;
    1717        f->u.real.d = 36;
    1718        f->u.real.e = 4;
    1719        break;
    1720  #endif
    1721      default:
    1722        internal_error (&dtp->common, "bad real kind");
    1723        break;
    1724      }
    1725  }
    1726  
    1727  /* Output a real number with default format.
    1728     To guarantee that a binary -> decimal -> binary roundtrip conversion
    1729     recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
    1730     significant digits for REAL kinds 4, 8, 10, and 16, respectively.
    1731     Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
    1732     for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
    1733     Fortran standard requires outputting an extra digit when the scale
    1734     factor is 1 and when the magnitude of the value is such that E
    1735     editing is used. However, gfortran compensates for this, and thus
    1736     for list formatted the same number of significant digits is
    1737     generated both when using F and E editing.  */
    1738  
    1739  void
    1740  write_real (st_parameter_dt *dtp, const char *source, int kind)
    1741  {
    1742    fnode f ;
    1743    char buf_stack[BUF_STACK_SZ];
    1744    char str_buf[BUF_STACK_SZ];
    1745    char *buffer, *result;
    1746    size_t buf_size, res_len, flt_str_len;
    1747    int orig_scale = dtp->u.p.scale_factor;
    1748    dtp->u.p.scale_factor = 1;
    1749    set_fnode_default (dtp, &f, kind);
    1750  
    1751    /* Precision for snprintf call.  */
    1752    int precision = get_precision (dtp, &f, source, kind);
    1753  
    1754    /* String buffer to hold final result.  */
    1755    result = select_string (dtp, &f, str_buf, &res_len, kind);
    1756  
    1757    /* Scratch buffer to hold final result.  */
    1758    buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
    1759    
    1760    get_float_string (dtp, &f, source , kind, 1, buffer,
    1761                             precision, buf_size, result, &flt_str_len);
    1762    write_float_string (dtp, result, flt_str_len);
    1763  
    1764    dtp->u.p.scale_factor = orig_scale;
    1765    if (buf_size > BUF_STACK_SZ)
    1766      free (buffer);
    1767    if (res_len > BUF_STACK_SZ)
    1768      free (result);
    1769  }
    1770  
    1771  /* Similar to list formatted REAL output, for kPG0 where k > 0 we
    1772     compensate for the extra digit.  */
    1773  
    1774  void
    1775  write_real_w0 (st_parameter_dt *dtp, const char *source, int kind,
    1776  	       const fnode* f)
    1777  {
    1778    fnode ff;
    1779    char buf_stack[BUF_STACK_SZ];
    1780    char str_buf[BUF_STACK_SZ];
    1781    char *buffer, *result;
    1782    size_t buf_size, res_len, flt_str_len;
    1783    int comp_d = 0;
    1784  
    1785    set_fnode_default (dtp, &ff, kind);
    1786  
    1787    if (f->u.real.d > 0)
    1788      ff.u.real.d = f->u.real.d;
    1789    ff.format = f->format;
    1790  
    1791    /* For FMT_G, Compensate for extra digits when using scale factor, d
    1792       is not specified, and the magnitude is such that E editing
    1793       is used.  */
    1794    if (f->format == FMT_G)
    1795      {
    1796        if (dtp->u.p.scale_factor > 0 && f->u.real.d == 0)
    1797  	comp_d = 1;
    1798        else
    1799  	comp_d = 0;
    1800      }
    1801  
    1802    if (f->u.real.e >= 0)
    1803      ff.u.real.e = f->u.real.e;
    1804  
    1805    dtp->u.p.g0_no_blanks = 1;
    1806  
    1807    /* Precision for snprintf call.  */
    1808    int precision = get_precision (dtp, &ff, source, kind);
    1809  
    1810    /* String buffer to hold final result.  */
    1811    result = select_string (dtp, &ff, str_buf, &res_len, kind);
    1812  
    1813    buffer = select_buffer (dtp, &ff, precision, buf_stack, &buf_size, kind);
    1814  
    1815    get_float_string (dtp, &ff, source , kind, comp_d, buffer,
    1816  		    precision, buf_size, result, &flt_str_len);
    1817    write_float_string (dtp, result, flt_str_len);
    1818  
    1819    dtp->u.p.g0_no_blanks = 0;
    1820    if (buf_size > BUF_STACK_SZ)
    1821      free (buffer);
    1822    if (res_len > BUF_STACK_SZ)
    1823      free (result);
    1824  }
    1825  
    1826  
    1827  static void
    1828  write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
    1829  {
    1830    char semi_comma =
    1831  	dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
    1832  
    1833    /* Set for no blanks so we get a string result with no leading
    1834       blanks.  We will pad left later.  */
    1835    dtp->u.p.g0_no_blanks = 1;
    1836  
    1837    fnode f ;
    1838    char buf_stack[BUF_STACK_SZ];
    1839    char str1_buf[BUF_STACK_SZ];
    1840    char str2_buf[BUF_STACK_SZ];
    1841    char *buffer, *result1, *result2;
    1842    size_t buf_size, res_len1, res_len2, flt_str_len1, flt_str_len2;
    1843    int width, lblanks, orig_scale = dtp->u.p.scale_factor;
    1844  
    1845    dtp->u.p.scale_factor = 1;
    1846    set_fnode_default (dtp, &f, kind);
    1847  
    1848    /* Set width for two values, parenthesis, and comma.  */
    1849    width = 2 * f.u.real.w + 3;
    1850  
    1851    /* Set for no blanks so we get a string result with no leading
    1852       blanks.  We will pad left later.  */
    1853    dtp->u.p.g0_no_blanks = 1;
    1854  
    1855    /* Precision for snprintf call.  */
    1856    int precision = get_precision (dtp, &f, source, kind);
    1857  
    1858    /* String buffers to hold final result.  */
    1859    result1 = select_string (dtp, &f, str1_buf, &res_len1, kind);
    1860    result2 = select_string (dtp, &f, str2_buf, &res_len2, kind);
    1861  
    1862    buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
    1863  
    1864    get_float_string (dtp, &f, source , kind, 0, buffer,
    1865                             precision, buf_size, result1, &flt_str_len1);
    1866    get_float_string (dtp, &f, source + size / 2 , kind, 0, buffer,
    1867                             precision, buf_size, result2, &flt_str_len2);
    1868    if (!dtp->u.p.namelist_mode)
    1869      {
    1870        lblanks = width - flt_str_len1 - flt_str_len2 - 3;
    1871        write_x (dtp, lblanks, lblanks);
    1872      }
    1873    write_char (dtp, '(');
    1874    write_float_string (dtp, result1, flt_str_len1);
    1875    write_char (dtp, semi_comma);
    1876    write_float_string (dtp, result2, flt_str_len2);
    1877    write_char (dtp, ')');
    1878  
    1879    dtp->u.p.scale_factor = orig_scale;
    1880    dtp->u.p.g0_no_blanks = 0;
    1881    if (buf_size > BUF_STACK_SZ)
    1882      free (buffer);
    1883    if (res_len1 > BUF_STACK_SZ)
    1884      free (result1);
    1885    if (res_len2 > BUF_STACK_SZ)
    1886      free (result2);
    1887  }
    1888  
    1889  
    1890  /* Write the separator between items.  */
    1891  
    1892  static void
    1893  write_separator (st_parameter_dt *dtp)
    1894  {
    1895    char *p;
    1896  
    1897    p = write_block (dtp, options.separator_len);
    1898    if (p == NULL)
    1899      return;
    1900    if (unlikely (is_char4_unit (dtp)))
    1901      {
    1902        gfc_char4_t *p4 = (gfc_char4_t *) p;
    1903        memcpy4 (p4, options.separator, options.separator_len);
    1904      }
    1905    else
    1906      memcpy (p, options.separator, options.separator_len);
    1907  }
    1908  
    1909  
    1910  /* Write an item with list formatting.
    1911     TODO: handle skipping to the next record correctly, particularly
    1912     with strings.  */
    1913  
    1914  static void
    1915  list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
    1916  			     size_t size)
    1917  {
    1918    if (dtp->u.p.current_unit == NULL)
    1919      return;
    1920  
    1921    if (dtp->u.p.first_item)
    1922      {
    1923        dtp->u.p.first_item = 0;
    1924        if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
    1925  	write_char (dtp, ' ');
    1926      }
    1927    else
    1928      {
    1929        if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
    1930  	  (dtp->u.p.current_unit->delim_status != DELIM_NONE
    1931  	   && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
    1932        write_separator (dtp);
    1933      }
    1934  
    1935    switch (type)
    1936      {
    1937      case BT_INTEGER:
    1938        write_integer (dtp, p, kind);
    1939        break;
    1940      case BT_LOGICAL:
    1941        write_logical (dtp, p, kind);
    1942        break;
    1943      case BT_CHARACTER:
    1944        write_character (dtp, p, kind, size, DELIM);
    1945        break;
    1946      case BT_REAL:
    1947        write_real (dtp, p, kind);
    1948        break;
    1949      case BT_COMPLEX:
    1950        write_complex (dtp, p, kind, size);
    1951        break;
    1952      case BT_CLASS:
    1953        {
    1954  	  int unit = dtp->u.p.current_unit->unit_number;
    1955  	  char iotype[] = "LISTDIRECTED";
    1956  	  gfc_charlen_type iotype_len = 12;
    1957  	  char tmp_iomsg[IOMSG_LEN] = "";
    1958  	  char *child_iomsg;
    1959  	  gfc_charlen_type child_iomsg_len;
    1960  	  int noiostat;
    1961  	  int *child_iostat = NULL;
    1962  	  gfc_full_array_i4 vlist;
    1963  
    1964  	  GFC_DESCRIPTOR_DATA(&vlist) = NULL;
    1965  	  GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
    1966  
    1967  	  /* Set iostat, intent(out).  */
    1968  	  noiostat = 0;
    1969  	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
    1970  			  dtp->common.iostat : &noiostat;
    1971  
    1972  	  /* Set iomsge, intent(inout).  */
    1973  	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
    1974  	    {
    1975  	      child_iomsg = dtp->common.iomsg;
    1976  	      child_iomsg_len = dtp->common.iomsg_len;
    1977  	    }
    1978  	  else
    1979  	    {
    1980  	      child_iomsg = tmp_iomsg;
    1981  	      child_iomsg_len = IOMSG_LEN;
    1982  	    }
    1983  
    1984  	  /* Call the user defined formatted WRITE procedure.  */
    1985  	  dtp->u.p.current_unit->child_dtio++;
    1986  	  dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
    1987  			      child_iostat, child_iomsg,
    1988  			      iotype_len, child_iomsg_len);
    1989  	  dtp->u.p.current_unit->child_dtio--;
    1990        }
    1991        break;
    1992      default:
    1993        internal_error (&dtp->common, "list_formatted_write(): Bad type");
    1994      }
    1995  
    1996    fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
    1997    dtp->u.p.char_flag = (type == BT_CHARACTER);
    1998  }
    1999  
    2000  
    2001  void
    2002  list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
    2003  		      size_t size, size_t nelems)
    2004  {
    2005    size_t elem;
    2006    char *tmp;
    2007    size_t stride = type == BT_CHARACTER ?
    2008  		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
    2009  
    2010    tmp = (char *) p;
    2011  
    2012    /* Big loop over all the elements.  */
    2013    for (elem = 0; elem < nelems; elem++)
    2014      {
    2015        dtp->u.p.item_count++;
    2016        list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
    2017      }
    2018  }
    2019  
    2020  /*			NAMELIST OUTPUT
    2021  
    2022     nml_write_obj writes a namelist object to the output stream.  It is called
    2023     recursively for derived type components:
    2024  	obj    = is the namelist_info for the current object.
    2025  	offset = the offset relative to the address held by the object for
    2026  		 derived type arrays.
    2027  	base   = is the namelist_info of the derived type, when obj is a
    2028  		 component.
    2029  	base_name = the full name for a derived type, including qualifiers
    2030  		    if any.
    2031     The returned value is a pointer to the object beyond the last one
    2032     accessed, including nested derived types.  Notice that the namelist is
    2033     a linear linked list of objects, including derived types and their
    2034     components.  A tree, of sorts, is implied by the compound names of
    2035     the derived type components and this is how this function recurses through
    2036     the list.  */
    2037  
    2038  /* A generous estimate of the number of characters needed to print
    2039     repeat counts and indices, including commas, asterices and brackets.  */
    2040  
    2041  #define NML_DIGITS 20
    2042  
    2043  static void
    2044  namelist_write_newline (st_parameter_dt *dtp)
    2045  {
    2046    if (!is_internal_unit (dtp))
    2047      {
    2048  #ifdef HAVE_CRLF
    2049        write_character (dtp, "\r\n", 1, 2, NODELIM);
    2050  #else
    2051        write_character (dtp, "\n", 1, 1, NODELIM);
    2052  #endif
    2053        return;
    2054      }
    2055  
    2056    if (is_array_io (dtp))
    2057      {
    2058        gfc_offset record;
    2059        int finished;
    2060        char *p;
    2061        int length = dtp->u.p.current_unit->bytes_left;
    2062  
    2063        p = write_block (dtp, length);
    2064        if (p == NULL)
    2065  	return;
    2066  
    2067        if (unlikely (is_char4_unit (dtp)))
    2068  	{
    2069  	  gfc_char4_t *p4 = (gfc_char4_t *) p;
    2070  	  memset4 (p4, ' ', length);
    2071  	}
    2072        else
    2073  	memset (p, ' ', length);
    2074  
    2075        /* Now that the current record has been padded out,
    2076  	 determine where the next record in the array is. */
    2077        record = next_array_record (dtp, dtp->u.p.current_unit->ls,
    2078  				  &finished);
    2079        if (finished)
    2080  	dtp->u.p.current_unit->endfile = AT_ENDFILE;
    2081        else
    2082  	{
    2083  	  /* Now seek to this record */
    2084  	  record = record * dtp->u.p.current_unit->recl;
    2085  
    2086  	  if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
    2087  	    {
    2088  	      generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
    2089  	      return;
    2090  	    }
    2091  
    2092  	  dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
    2093  	}
    2094      }
    2095    else
    2096      write_character (dtp, " ", 1, 1, NODELIM);
    2097  }
    2098  
    2099  
    2100  static namelist_info *
    2101  nml_write_obj (st_parameter_dt *dtp, namelist_info *obj, index_type offset,
    2102  	       namelist_info *base, char *base_name)
    2103  {
    2104    int rep_ctr;
    2105    int num;
    2106    int nml_carry;
    2107    int len;
    2108    index_type obj_size;
    2109    index_type nelem;
    2110    size_t dim_i;
    2111    size_t clen;
    2112    index_type elem_ctr;
    2113    size_t obj_name_len;
    2114    void *p;
    2115    char cup;
    2116    char *obj_name;
    2117    char *ext_name;
    2118    char *q;
    2119    size_t ext_name_len;
    2120    char rep_buff[NML_DIGITS];
    2121    namelist_info *cmp;
    2122    namelist_info *retval = obj->next;
    2123    size_t base_name_len;
    2124    size_t base_var_name_len;
    2125    size_t tot_len;
    2126  
    2127    /* Set the character to be used to separate values
    2128       to a comma or semi-colon.  */
    2129  
    2130    char semi_comma =
    2131  	dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
    2132  
    2133    /* Write namelist variable names in upper case. If a derived type,
    2134       nothing is output.  If a component, base and base_name are set.  */
    2135  
    2136    if (obj->type != BT_DERIVED || obj->dtio_sub != NULL)
    2137      {
    2138        namelist_write_newline (dtp);
    2139        write_character (dtp, " ", 1, 1, NODELIM);
    2140  
    2141        len = 0;
    2142        if (base)
    2143  	{
    2144  	  len = strlen (base->var_name);
    2145  	  base_name_len = strlen (base_name);
    2146  	  for (dim_i = 0; dim_i < base_name_len; dim_i++)
    2147              {
    2148  	      cup = safe_toupper (base_name[dim_i]);
    2149  	      write_character (dtp, &cup, 1, 1, NODELIM);
    2150              }
    2151  	}
    2152        clen = strlen (obj->var_name);
    2153        for (dim_i = len; dim_i < clen; dim_i++)
    2154  	{
    2155  	  cup = safe_toupper (obj->var_name[dim_i]);
    2156  	  if (cup == '+')
    2157  	    cup = '%';
    2158  	  write_character (dtp, &cup, 1, 1, NODELIM);
    2159  	}
    2160        write_character (dtp, "=", 1, 1, NODELIM);
    2161      }
    2162  
    2163    /* Counts the number of data output on a line, including names.  */
    2164  
    2165    num = 1;
    2166  
    2167    len = obj->len;
    2168  
    2169    switch (obj->type)
    2170      {
    2171  
    2172      case BT_REAL:
    2173        obj_size = size_from_real_kind (len);
    2174        break;
    2175  
    2176      case BT_COMPLEX:
    2177        obj_size = size_from_complex_kind (len);
    2178        break;
    2179  
    2180      case BT_CHARACTER:
    2181        obj_size = obj->string_length;
    2182        break;
    2183  
    2184      default:
    2185        obj_size = len;
    2186      }
    2187  
    2188    if (obj->var_rank)
    2189      obj_size = obj->size;
    2190  
    2191    /* Set the index vector and count the number of elements.  */
    2192  
    2193    nelem = 1;
    2194    for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
    2195      {
    2196        obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
    2197        nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
    2198      }
    2199  
    2200    /* Main loop to output the data held in the object.  */
    2201  
    2202    rep_ctr = 1;
    2203    for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
    2204      {
    2205  
    2206        /* Build the pointer to the data value.  The offset is passed by
    2207  	 recursive calls to this function for arrays of derived types.
    2208  	 Is NULL otherwise.  */
    2209  
    2210        p = (void *)(obj->mem_pos + elem_ctr * obj_size);
    2211        p += offset;
    2212  
    2213        /* Check for repeat counts of intrinsic types.  */
    2214  
    2215        if ((elem_ctr < (nelem - 1)) &&
    2216  	  (obj->type != BT_DERIVED) &&
    2217  	  !memcmp (p, (void *)(p + obj_size ), obj_size ))
    2218  	{
    2219  	  rep_ctr++;
    2220  	}
    2221  
    2222        /* Execute a repeated output.  Note the flag no_leading_blank that
    2223  	 is used in the functions used to output the intrinsic types.  */
    2224  
    2225        else
    2226  	{
    2227  	  if (rep_ctr > 1)
    2228  	    {
    2229  	      snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
    2230  	      write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
    2231  	      dtp->u.p.no_leading_blank = 1;
    2232  	    }
    2233  	  num++;
    2234  
    2235  	  /* Output the data, if an intrinsic type, or recurse into this
    2236  	     routine to treat derived types.  */
    2237  
    2238  	  switch (obj->type)
    2239  	    {
    2240  
    2241  	    case BT_INTEGER:
    2242  	      write_integer (dtp, p, len);
    2243                break;
    2244  
    2245  	    case BT_LOGICAL:
    2246  	      write_logical (dtp, p, len);
    2247                break;
    2248  
    2249  	    case BT_CHARACTER:
    2250  	      if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
    2251  		write_character (dtp, p, 4, obj->string_length, DELIM);
    2252  	      else
    2253  		write_character (dtp, p, 1, obj->string_length, DELIM);
    2254                break;
    2255  
    2256  	    case BT_REAL:
    2257  	      write_real (dtp, p, len);
    2258                break;
    2259  
    2260  	   case BT_COMPLEX:
    2261  	      dtp->u.p.no_leading_blank = 0;
    2262  	      num++;
    2263                write_complex (dtp, p, len, obj_size);
    2264                break;
    2265  
    2266  	    case BT_DERIVED:
    2267  	    case BT_CLASS:
    2268  	      /* To treat a derived type, we need to build two strings:
    2269  		 ext_name = the name, including qualifiers that prepends
    2270  			    component names in the output - passed to
    2271  			    nml_write_obj.
    2272  		 obj_name = the derived type name with no qualifiers but %
    2273  			    appended.  This is used to identify the
    2274  			    components.  */
    2275  
    2276  	      /* First ext_name => get length of all possible components  */
    2277  	      if (obj->dtio_sub != NULL)
    2278  		{
    2279  		  int unit = dtp->u.p.current_unit->unit_number;
    2280  		  char iotype[] = "NAMELIST";
    2281  		  gfc_charlen_type iotype_len = 8;
    2282  		  char tmp_iomsg[IOMSG_LEN] = "";
    2283  		  char *child_iomsg;
    2284  		  gfc_charlen_type child_iomsg_len;
    2285  		  int noiostat;
    2286  		  int *child_iostat = NULL;
    2287  		  gfc_full_array_i4 vlist;
    2288  		  formatted_dtio dtio_ptr = (formatted_dtio)obj->dtio_sub;
    2289  
    2290  		  GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
    2291  
    2292  		  /* Set iostat, intent(out).  */
    2293  		  noiostat = 0;
    2294  		  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
    2295  				  dtp->common.iostat : &noiostat;
    2296  
    2297  		  /* Set iomsg, intent(inout).  */
    2298  		  if (dtp->common.flags & IOPARM_HAS_IOMSG)
    2299  		    {
    2300  		      child_iomsg = dtp->common.iomsg;
    2301  		      child_iomsg_len = dtp->common.iomsg_len;
    2302  		    }
    2303  		  else
    2304  		    {
    2305  		      child_iomsg = tmp_iomsg;
    2306  		      child_iomsg_len = IOMSG_LEN;
    2307  		    }
    2308  
    2309  		  /* Call the user defined formatted WRITE procedure.  */
    2310  		  dtp->u.p.current_unit->child_dtio++;
    2311  		  if (obj->type == BT_DERIVED)
    2312  		    {
    2313  		      /* Build a class container.  */
    2314  		      gfc_class list_obj;
    2315  		      list_obj.data = p;
    2316  		      list_obj.vptr = obj->vtable;
    2317  		      list_obj.len = 0;
    2318  		      dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
    2319  				child_iostat, child_iomsg,
    2320  				iotype_len, child_iomsg_len);
    2321  		    }
    2322  		  else
    2323  		    {
    2324  		      dtio_ptr (p, &unit, iotype, &vlist,
    2325  				child_iostat, child_iomsg,
    2326  				iotype_len, child_iomsg_len);
    2327  		    }
    2328  		  dtp->u.p.current_unit->child_dtio--;
    2329  
    2330  		  goto obj_loop;
    2331  		}
    2332  
    2333  	      base_name_len = base_name ? strlen (base_name) : 0;
    2334  	      base_var_name_len = base ? strlen (base->var_name) : 0;
    2335  	      ext_name_len = base_name_len + base_var_name_len
    2336  		+ strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
    2337  	      ext_name = xmalloc (ext_name_len);
    2338  
    2339  	      if (base_name)
    2340  		memcpy (ext_name, base_name, base_name_len);
    2341  	      clen = strlen (obj->var_name + base_var_name_len);
    2342  	      memcpy (ext_name + base_name_len,
    2343  		      obj->var_name + base_var_name_len, clen);
    2344  
    2345  	      /* Append the qualifier.  */
    2346  
    2347  	      tot_len = base_name_len + clen;
    2348  	      for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
    2349  		{
    2350  		  if (!dim_i)
    2351  		    {
    2352  		      ext_name[tot_len] = '(';
    2353  		      tot_len++;
    2354  		    }
    2355  		  snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
    2356  			    (int) obj->ls[dim_i].idx);
    2357  		  tot_len += strlen (ext_name + tot_len);
    2358  		  ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
    2359  		  tot_len++;
    2360  		}
    2361  
    2362  	      ext_name[tot_len] = '\0';
    2363  	      for (q = ext_name; *q; q++)
    2364  		if (*q == '+')
    2365  		  *q = '%';
    2366  
    2367  	      /* Now obj_name.  */
    2368  
    2369  	      obj_name_len = strlen (obj->var_name) + 1;
    2370  	      obj_name = xmalloc (obj_name_len + 1);
    2371  	      memcpy (obj_name, obj->var_name, obj_name_len-1);
    2372  	      memcpy (obj_name + obj_name_len-1, "%", 2);
    2373  
    2374  	      /* Now loop over the components. Update the component pointer
    2375  		 with the return value from nml_write_obj => this loop jumps
    2376  		 past nested derived types.  */
    2377  
    2378  	      for (cmp = obj->next;
    2379  		   cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
    2380  		   cmp = retval)
    2381  		{
    2382  		  retval = nml_write_obj (dtp, cmp,
    2383  					  (index_type)(p - obj->mem_pos),
    2384  					  obj, ext_name);
    2385  		}
    2386  
    2387  	      free (obj_name);
    2388  	      free (ext_name);
    2389  	      goto obj_loop;
    2390  
    2391              default:
    2392  	      internal_error (&dtp->common, "Bad type for namelist write");
    2393              }
    2394  
    2395  	  /* Reset the leading blank suppression, write a comma (or semi-colon)
    2396  	     and, if 5 values have been output, write a newline and advance
    2397  	     to column 2. Reset the repeat counter.  */
    2398  
    2399  	  dtp->u.p.no_leading_blank = 0;
    2400  	  if (obj->type == BT_CHARACTER)
    2401  	    {
    2402  	      if (dtp->u.p.nml_delim != '\0')
    2403  		write_character (dtp, &semi_comma, 1, 1, NODELIM);
    2404  	    }
    2405  	  else
    2406  	    write_character (dtp, &semi_comma, 1, 1, NODELIM);
    2407  	  if (num > 5)
    2408  	    {
    2409  	      num = 0;
    2410  	      if (dtp->u.p.nml_delim == '\0')
    2411  		write_character (dtp, &semi_comma, 1, 1, NODELIM);
    2412  	      namelist_write_newline (dtp);
    2413  	      write_character (dtp, " ", 1, 1, NODELIM);
    2414  	    }
    2415  	  rep_ctr = 1;
    2416  	}
    2417  
    2418      /* Cycle through and increment the index vector.  */
    2419  
    2420  obj_loop:
    2421  
    2422        nml_carry = 1;
    2423        for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
    2424  	{
    2425  	  obj->ls[dim_i].idx += nml_carry ;
    2426  	  nml_carry = 0;
    2427  	  if (obj->ls[dim_i].idx  > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
    2428  	    {
    2429  	      obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
    2430  	      nml_carry = 1;
    2431  	    }
    2432  	 }
    2433      }
    2434  
    2435    /* Return a pointer beyond the furthest object accessed.  */
    2436  
    2437    return retval;
    2438  }
    2439  
    2440  
    2441  /* This is the entry function for namelist writes.  It outputs the name
    2442     of the namelist and iterates through the namelist by calls to
    2443     nml_write_obj.  The call below has dummys in the arguments used in
    2444     the treatment of derived types.  */
    2445  
    2446  void
    2447  namelist_write (st_parameter_dt *dtp)
    2448  {
    2449    namelist_info *t1, *t2, *dummy = NULL;
    2450    index_type dummy_offset = 0;
    2451    char c;
    2452    char *dummy_name = NULL;
    2453  
    2454    /* Set the delimiter for namelist output.  */
    2455    switch (dtp->u.p.current_unit->delim_status)
    2456      {
    2457        case DELIM_APOSTROPHE:
    2458          dtp->u.p.nml_delim = '\'';
    2459  	break;
    2460        case DELIM_QUOTE:
    2461        case DELIM_UNSPECIFIED:
    2462  	dtp->u.p.nml_delim = '"';
    2463  	break;
    2464        default:
    2465  	dtp->u.p.nml_delim = '\0';
    2466      }
    2467  
    2468    write_character (dtp, "&", 1, 1, NODELIM);
    2469  
    2470    /* Write namelist name in upper case - f95 std.  */
    2471    for (gfc_charlen_type i = 0; i < dtp->namelist_name_len; i++ )
    2472      {
    2473        c = safe_toupper (dtp->namelist_name[i]);
    2474        write_character (dtp, &c, 1 ,1, NODELIM);
    2475      }
    2476  
    2477    if (dtp->u.p.ionml != NULL)
    2478      {
    2479        t1 = dtp->u.p.ionml;
    2480        while (t1 != NULL)
    2481  	{
    2482  	  t2 = t1;
    2483  	  t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
    2484  	}
    2485      }
    2486  
    2487    namelist_write_newline (dtp);
    2488    write_character (dtp, " /", 1, 2, NODELIM);
    2489  }
    2490  
    2491  #undef NML_DIGITS