/* Copyright (C) 2002-2025 Free Software Foundation, Inc.
   Contributed by Andy Vaught
   Namelist transfer functions contributed by Paul Thomas
   F2003 I/O support contributed by Jerry DeLisle

This file is part of the GNU Fortran runtime library (libgfortran).

Libgfortran is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

Libgfortran is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */


/* transfer.c -- Top level handling of data transfer statements.  */

#include "io.h"
#include "fbuf.h"
#include "format.h"
#include "unix.h"
#include "async.h"
#include <string.h>
#include <errno.h>


/* Calling conventions:  Data transfer statements are unlike other
   library calls in that they extend over several calls.

   The first call is always a call to st_read() or st_write().  These
   subroutines return no status unless a namelist read or write is
   being done, in which case there is the usual status.  No further
   calls are necessary in this case.

   For other sorts of data transfer, there are zero or more data
   transfer statement that depend on the format of the data transfer
   statement. For READ (and for backwards compatibily: for WRITE), one has

      transfer_integer
      transfer_logical
      transfer_character
      transfer_character_wide
      transfer_real
      transfer_complex
      transfer_real128
      transfer_complex128
      transfer_unsigned

    and for WRITE

      transfer_integer_write
      transfer_logical_write
      transfer_character_write
      transfer_character_wide_write
      transfer_real_write
      transfer_complex_write
      transfer_real128_write
      transfer_complex128_write
      transfer_unsigned_write

    These subroutines do not return status. The *128 functions
    are in the file transfer128.c.

    The last call is a call to st_[read|write]_done().  While
    something can easily go wrong with the initial st_read() or
    st_write(), an error inhibits any data from actually being
    transferred.  */

extern void transfer_integer (st_parameter_dt *, void *, int);
export_proto(transfer_integer);

extern void transfer_integer_write (st_parameter_dt *, void *, int);
export_proto(transfer_integer_write);

extern void transfer_unsigned (st_parameter_dt *, void *, int);
export_proto(transfer_unsigned);

extern void transfer_unsigned_write (st_parameter_dt *, void *, int);
export_proto(transfer_unsigned_write);

extern void transfer_real (st_parameter_dt *, void *, int);
export_proto(transfer_real);

extern void transfer_real_write (st_parameter_dt *, void *, int);
export_proto(transfer_real_write);

extern void transfer_logical (st_parameter_dt *, void *, int);
export_proto(transfer_logical);

extern void transfer_logical_write (st_parameter_dt *, void *, int);
export_proto(transfer_logical_write);

extern void transfer_character (st_parameter_dt *, void *, gfc_charlen_type);
export_proto(transfer_character);

extern void transfer_character_write (st_parameter_dt *, void *, gfc_charlen_type);
export_proto(transfer_character_write);

extern void transfer_character_wide (st_parameter_dt *, void *, gfc_charlen_type, int);
export_proto(transfer_character_wide);

extern void transfer_character_wide_write (st_parameter_dt *,
					   void *, gfc_charlen_type, int);
export_proto(transfer_character_wide_write);

extern void transfer_complex (st_parameter_dt *, void *, int);
export_proto(transfer_complex);

extern void transfer_complex_write (st_parameter_dt *, void *, int);
export_proto(transfer_complex_write);

extern void transfer_array (st_parameter_dt *, gfc_array_char *, int,
			    gfc_charlen_type);
export_proto(transfer_array);

extern void transfer_array_write (st_parameter_dt *, gfc_array_char *, int,
			    gfc_charlen_type);
export_proto(transfer_array_write);

/* User defined derived type input/output.  */
extern void
transfer_derived (st_parameter_dt *dtp, void *dtio_source, void *dtio_proc);
export_proto(transfer_derived);

extern void
transfer_derived_write (st_parameter_dt *dtp, void *dtio_source, void *dtio_proc);
export_proto(transfer_derived_write);

static void us_read (st_parameter_dt *, int);
static void us_write (st_parameter_dt *, int);
static void next_record_r_unf (st_parameter_dt *, int);
static void next_record_w_unf (st_parameter_dt *, int);

static const st_option advance_opt[] = {
  {"yes", ADVANCE_YES},
  {"no", ADVANCE_NO},
  {NULL, 0}
};


static const st_option decimal_opt[] = {
  {"point", DECIMAL_POINT},
  {"comma", DECIMAL_COMMA},
  {NULL, 0}
};

static const st_option round_opt[] = {
  {"up", ROUND_UP},
  {"down", ROUND_DOWN},
  {"zero", ROUND_ZERO},
  {"nearest", ROUND_NEAREST},
  {"compatible", ROUND_COMPATIBLE},
  {"processor_defined", ROUND_PROCDEFINED},
  {NULL, 0}
};


static const st_option sign_opt[] = {
  {"plus", SIGN_SP},
  {"suppress", SIGN_SS},
  {"processor_defined", SIGN_S},
  {NULL, 0}
};

static const st_option blank_opt[] = {
  {"null", BLANK_NULL},
  {"zero", BLANK_ZERO},
  {NULL, 0}
};

static const st_option delim_opt[] = {
  {"apostrophe", DELIM_APOSTROPHE},
  {"quote", DELIM_QUOTE},
  {"none", DELIM_NONE},
  {NULL, 0}
};

static const st_option pad_opt[] = {
  {"yes", PAD_YES},
  {"no", PAD_NO},
  {NULL, 0}
};

static const st_option async_opt[] = {
  {"yes", ASYNC_YES},
  {"no", ASYNC_NO},
  {NULL, 0}
};

typedef enum
{ FORMATTED_SEQUENTIAL, UNFORMATTED_SEQUENTIAL,
  FORMATTED_DIRECT, UNFORMATTED_DIRECT, FORMATTED_STREAM,
  UNFORMATTED_STREAM, FORMATTED_UNSPECIFIED
}
file_mode;


static file_mode
current_mode (st_parameter_dt *dtp)
{
  file_mode m;

  m = FORMATTED_UNSPECIFIED;

  if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
    {
      m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
	FORMATTED_DIRECT : UNFORMATTED_DIRECT;
    }
  else if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
    {
      m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
	FORMATTED_SEQUENTIAL : UNFORMATTED_SEQUENTIAL;
    }
  else if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
    {
      m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
	FORMATTED_STREAM : UNFORMATTED_STREAM;
    }

  return m;
}


/* Mid level data transfer statements.  */

/* Read sequential file - internal unit  */

static char *
read_sf_internal (st_parameter_dt *dtp, size_t *length)
{
  static char *empty_string[0];
  char *base = NULL;
  size_t lorig;

  /* Zero size array gives internal unit len of 0.  Nothing to read. */
  if (dtp->internal_unit_len == 0
      && dtp->u.p.current_unit->pad_status == PAD_NO)
    hit_eof (dtp);

  /* There are some cases with mixed DTIO where we have read a character
     and saved it in the last character buffer, so we need to backup.  */
  if (unlikely (dtp->u.p.current_unit->child_dtio > 0 &&
		dtp->u.p.current_unit->last_char != EOF - 1))
    {
      dtp->u.p.current_unit->last_char = EOF - 1;
      sseek (dtp->u.p.current_unit->s, -1, SEEK_CUR);
    }

  /* To support legacy code we have to scan the input string one byte
     at a time because we don't know where an early comma may be and the
     requested length could go past the end of a comma shortened
     string.  We only do this if -std=legacy was given at compile
     time.  We also do not support this on kind=4 strings.  */
  if (unlikely(compile_options.warn_std == 0)) // the slow legacy way.
    {
      size_t n;
      size_t tmp = 1;
      char *q;

      /* If we have seen an eor previously, return a length of 0.  The
	 caller is responsible for correctly padding the input field.  */
      if (dtp->u.p.sf_seen_eor)
	{
	  *length = 0;
	  /* Just return something that isn't a NULL pointer, otherwise the
	     caller thinks an error occurred.  */
	  return (char*) empty_string;
	}

      /* Get the first character of the string to establish the base
	 address and check for comma or end-of-record condition.  */
      base = mem_alloc_r (dtp->u.p.current_unit->s, &tmp);
      if (tmp == 0)
	{
	  dtp->u.p.sf_seen_eor = 1;
	  *length = 0;
	  return (char*) empty_string;
	}
      if (*base == ',')
	{
	  dtp->u.p.current_unit->bytes_left--;
	  *length = 0;
	  return (char*) empty_string;
	}

      /* Now we scan the rest and deal with either an end-of-file
         condition or a comma, as needed.  */
      for (n = 1; n < *length; n++)
	{
	  q = mem_alloc_r (dtp->u.p.current_unit->s, &tmp);
	  if (tmp == 0)
	    {
	      hit_eof (dtp);
	      return NULL;
	    }
	  if (*q == ',')
	    {
	      dtp->u.p.current_unit->bytes_left -= n;
	      *length = n;
	      break;
	    }
	}
    }
  else // the fast way
    {
      lorig = *length;
      if (is_char4_unit(dtp))
	{
	  gfc_char4_t *p = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s,
			    length);
	  base = fbuf_alloc (dtp->u.p.current_unit, lorig);
	  for (size_t i = 0; i < *length; i++, p++)
	    base[i] = *p > 255 ? '?' : (unsigned char) *p;
	}
      else
	base = mem_alloc_r (dtp->u.p.current_unit->s, length);

      if (unlikely (lorig > *length))
	{
	  hit_eof (dtp);
	  return NULL;
	}
    }

  dtp->u.p.current_unit->bytes_left -= *length;

  if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
      dtp->u.p.current_unit->has_size)
    dtp->u.p.current_unit->size_used += (GFC_IO_INT) *length;

  return base;

}

/* When reading sequential formatted records we have a problem.  We
   don't know how long the line is until we read the trailing newline,
   and we don't want to read too much.  If we read too much, we might
   have to do a physical seek backwards depending on how much data is
   present, and devices like terminals aren't seekable and would cause
   an I/O error.

   Given this, the solution is to read a byte at a time, stopping if
   we hit the newline.  For small allocations, we use a static buffer.
   For larger allocations, we are forced to allocate memory on the
   heap.  Hopefully this won't happen very often.  */

/* Read sequential file - external unit */

static char *
read_sf (st_parameter_dt *dtp, size_t *length)
{
  static char *empty_string[0];
  size_t lorig, n;
  int q, q2;
  int seen_comma;

  /* If we have seen an eor previously, return a length of 0.  The
     caller is responsible for correctly padding the input field.  */
  if (dtp->u.p.sf_seen_eor)
    {
      *length = 0;
      /* Just return something that isn't a NULL pointer, otherwise the
         caller thinks an error occurred.  */
      return (char*) empty_string;
    }

  /* There are some cases with mixed DTIO where we have read a character
     and saved it in the last character buffer, so we need to backup.  */
  if (unlikely (dtp->u.p.current_unit->child_dtio > 0 &&
		dtp->u.p.current_unit->last_char != EOF - 1))
    {
      dtp->u.p.current_unit->last_char = EOF - 1;
      fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
    }

  n = seen_comma = 0;

  /* Read data into format buffer and scan through it.  */
  lorig = *length;

  while (n < *length)
    {
      q = fbuf_getc (dtp->u.p.current_unit);
      if (q == EOF)
	break;
      else if (dtp->u.p.current_unit->flags.cc != CC_NONE
	       && (q == '\n' || q == '\r'))
	{
	  /* Unexpected end of line. Set the position.  */
	  dtp->u.p.sf_seen_eor = 1;

	  /* If we see an EOR during non-advancing I/O, we need to skip
	     the rest of the I/O statement.  Set the corresponding flag.  */
	  if (dtp->u.p.advance_status == ADVANCE_NO || dtp->u.p.seen_dollar)
	    dtp->u.p.eor_condition = 1;

	  /* If we encounter a CR, it might be a CRLF.  */
	  if (q == '\r') /* Probably a CRLF */
	    {
	      /* See if there is an LF.  */
	      q2 = fbuf_getc (dtp->u.p.current_unit);
	      if (q2 == '\n')
		dtp->u.p.sf_seen_eor = 2;
	      else if (q2 != EOF) /* Oops, seek back.  */
		fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
	    }

	  /* Without padding, terminate the I/O statement without assigning
	     the value.  With padding, the value still needs to be assigned,
	     so we can just continue with a short read.  */
	  if (dtp->u.p.current_unit->pad_status == PAD_NO)
	    {
	      generate_error (&dtp->common, LIBERROR_EOR, NULL);
	      return NULL;
	    }

	  *length = n;
	  goto done;
	}
      /*  Short circuit the read if a comma is found during numeric input.
	  The flag is set to zero during character reads so that commas in
	  strings are not ignored  */
      else if (q == ',')
	if (dtp->u.p.sf_read_comma == 1)
	  {
            seen_comma = 1;
	    notify_std (&dtp->common, GFC_STD_GNU,
			"Comma in formatted numeric read.");
	    break;
	  }
      n++;
    }

  *length = n;

  /* A short read implies we hit EOF, unless we hit EOR, a comma, or
     some other stuff. Set the relevant flags.  */
  if (lorig > *length && !dtp->u.p.sf_seen_eor && !seen_comma)
    {
      if (n > 0)
        {
	  if (dtp->u.p.advance_status == ADVANCE_NO)
	    {
	      if (dtp->u.p.current_unit->pad_status == PAD_NO)
	        {
		  hit_eof (dtp);
		  return NULL;
		}
	      else
		dtp->u.p.eor_condition = 1;
	    }
	  else
	    dtp->u.p.at_eof = 1;
	}
      else if (dtp->u.p.advance_status == ADVANCE_NO
	       || dtp->u.p.current_unit->pad_status == PAD_NO
	       || dtp->u.p.current_unit->bytes_left
		    == dtp->u.p.current_unit->recl)
	{
	  hit_eof (dtp);
	  return NULL;
	}
    }

 done:

  dtp->u.p.current_unit->bytes_left -= n;

  if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
      dtp->u.p.current_unit->has_size)
    dtp->u.p.current_unit->size_used += (GFC_IO_INT) n;

  /* We can't call fbuf_getptr before the loop doing fbuf_getc, because
     fbuf_getc might reallocate the buffer.  So return current pointer
     minus all the advances, which is n plus up to two characters
     of newline or comma.  */
  return fbuf_getptr (dtp->u.p.current_unit)
	 - n - dtp->u.p.sf_seen_eor - seen_comma;
}


/* Function for reading the next couple of bytes from the current
   file, advancing the current position. We return NULL on end of record or
   end of file. This function is only for formatted I/O, unformatted uses
   read_block_direct.

   If the read is short, then it is because the current record does not
   have enough data to satisfy the read request and the file was
   opened with PAD=YES.  The caller must assume trailing spaces for
   short reads.  */

void *
read_block_form (st_parameter_dt *dtp, size_t *nbytes)
{
  char *source;
  size_t norig;

  if (!is_stream_io (dtp))
    {
      if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
	{
	  /* For preconnected units with default record length, set bytes left
	   to unit record length and proceed, otherwise error.  */
	  if (dtp->u.p.current_unit->unit_number == options.stdin_unit
	      && dtp->u.p.current_unit->recl == default_recl)
            dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
	  else
	    {
	      if (unlikely (dtp->u.p.current_unit->pad_status == PAD_NO)
		  && !is_internal_unit (dtp))
		{
		  /* Not enough data left.  */
		  generate_error (&dtp->common, LIBERROR_EOR, NULL);
		  return NULL;
		}
	    }

	  if (is_internal_unit(dtp))
	    {
	      if (*nbytes > 0 && dtp->u.p.current_unit->bytes_left == 0)
	        {
		  if (dtp->u.p.advance_status == ADVANCE_NO)
		    {
		      generate_error (&dtp->common, LIBERROR_EOR, NULL);
		      return NULL;
		    }
		}
	    }
	  else
	    {
	      if (unlikely (dtp->u.p.current_unit->bytes_left == 0))
		{
		  hit_eof (dtp);
		  return NULL;
		}
	    }

	  *nbytes = dtp->u.p.current_unit->bytes_left;
	}
    }

  if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
      (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL ||
       dtp->u.p.current_unit->flags.access == ACCESS_STREAM))
    {
      if (is_internal_unit (dtp))
	source = read_sf_internal (dtp, nbytes);
      else
	source = read_sf (dtp, nbytes);

      dtp->u.p.current_unit->strm_pos +=
	(gfc_offset) (*nbytes + dtp->u.p.sf_seen_eor);
      return source;
    }

  /* If we reach here, we can assume it's direct access.  */

  dtp->u.p.current_unit->bytes_left -= (gfc_offset) *nbytes;

  norig = *nbytes;
  source = fbuf_read (dtp->u.p.current_unit, nbytes);
  fbuf_seek (dtp->u.p.current_unit, *nbytes, SEEK_CUR);

  if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
      dtp->u.p.current_unit->has_size)
    dtp->u.p.current_unit->size_used += (GFC_IO_INT) *nbytes;

  if (norig != *nbytes)
    {
      /* Short read, this shouldn't happen.  */
      if (dtp->u.p.current_unit->pad_status == PAD_NO)
	{
	  generate_error (&dtp->common, LIBERROR_EOR, NULL);
	  source = NULL;
	}
    }

  dtp->u.p.current_unit->strm_pos += (gfc_offset) *nbytes;

  return source;
}


/* Read a block from a character(kind=4) internal unit, to be transferred into
   a character(kind=4) variable.  Note: Portions of this code borrowed from
   read_sf_internal.  */
void *
read_block_form4 (st_parameter_dt *dtp, size_t *nbytes)
{
  static gfc_char4_t *empty_string[0];
  gfc_char4_t *source;
  size_t lorig;

  if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
    *nbytes = dtp->u.p.current_unit->bytes_left;

  /* Zero size array gives internal unit len of 0.  Nothing to read. */
  if (dtp->internal_unit_len == 0
      && dtp->u.p.current_unit->pad_status == PAD_NO)
    hit_eof (dtp);

  /* If we have seen an eor previously, return a length of 0.  The
     caller is responsible for correctly padding the input field.  */
  if (dtp->u.p.sf_seen_eor)
    {
      *nbytes = 0;
      /* Just return something that isn't a NULL pointer, otherwise the
         caller thinks an error occurred.  */
      return empty_string;
    }

  lorig = *nbytes;
  source = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s, nbytes);

  if (unlikely (lorig > *nbytes))
    {
      hit_eof (dtp);
      return NULL;
    }

  dtp->u.p.current_unit->bytes_left -= *nbytes;

  if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
      dtp->u.p.current_unit->has_size)
    dtp->u.p.current_unit->size_used += (GFC_IO_INT) *nbytes;

  return source;
}


/* Reads a block directly into application data space.  This is for
   unformatted files.  */

static void
read_block_direct (st_parameter_dt *dtp, void *buf, size_t nbytes)
{
  ssize_t to_read_record;
  ssize_t have_read_record;
  ssize_t to_read_subrecord;
  ssize_t have_read_subrecord;
  int short_record;

  if (is_stream_io (dtp))
    {
      have_read_record = sread (dtp->u.p.current_unit->s, buf,
				nbytes);
      if (unlikely (have_read_record < 0))
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return;
	}

      dtp->u.p.current_unit->strm_pos += (gfc_offset) have_read_record;

      if (unlikely ((ssize_t) nbytes != have_read_record))
	{
	  /* Short read,  e.g. if we hit EOF.  For stream files,
	   we have to set the end-of-file condition.  */
          hit_eof (dtp);
	}
      return;
    }

  if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
    {
      if (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes)
	{
	  short_record = 1;
	  to_read_record = dtp->u.p.current_unit->bytes_left;
	  nbytes = to_read_record;
	}
      else
	{
	  short_record = 0;
	  to_read_record = nbytes;
	}

      dtp->u.p.current_unit->bytes_left -= to_read_record;

      to_read_record = sread (dtp->u.p.current_unit->s, buf, to_read_record);
      if (unlikely (to_read_record < 0))
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return;
	}

      if (to_read_record != (ssize_t) nbytes)
	{
	  /* Short read, e.g. if we hit EOF.  Apparently, we read
	   more than was written to the last record.  */
	  return;
	}

      if (unlikely (short_record))
	{
	  generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
	}
      return;
    }

  /* Unformatted sequential.  We loop over the subrecords, reading
     until the request has been fulfilled or the record has run out
     of continuation subrecords.  */

  /* Check whether we exceed the total record length.  */

  if (dtp->u.p.current_unit->flags.has_recl
      && ((gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left))
    {
      to_read_record = dtp->u.p.current_unit->bytes_left;
      short_record = 1;
    }
  else
    {
      to_read_record = nbytes;
      short_record = 0;
    }
  have_read_record = 0;

  while(1)
    {
      if (dtp->u.p.current_unit->bytes_left_subrecord
	  < (gfc_offset) to_read_record)
	{
	  to_read_subrecord = dtp->u.p.current_unit->bytes_left_subrecord;
	  to_read_record -= to_read_subrecord;
	}
      else
	{
	  to_read_subrecord = to_read_record;
	  to_read_record = 0;
	}

      dtp->u.p.current_unit->bytes_left_subrecord -= to_read_subrecord;

      have_read_subrecord = sread (dtp->u.p.current_unit->s,
				   buf + have_read_record, to_read_subrecord);
      if (unlikely (have_read_subrecord < 0))
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return;
	}

      have_read_record += have_read_subrecord;

      if (unlikely (to_read_subrecord != have_read_subrecord))
	{
	  /* Short read, e.g. if we hit EOF.  This means the record
	     structure has been corrupted, or the trailing record
	     marker would still be present.  */

	  generate_error (&dtp->common, LIBERROR_CORRUPT_FILE, NULL);
	  return;
	}

      if (to_read_record > 0)
	{
	  if (likely (dtp->u.p.current_unit->continued))
	    {
	      next_record_r_unf (dtp, 0);
	      us_read (dtp, 1);
	    }
	  else
	    {
	      /* Let's make sure the file position is correctly pre-positioned
		 for the next read statement.  */

	      dtp->u.p.current_unit->current_record = 0;
	      next_record_r_unf (dtp, 0);
	      generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
	      return;
	    }
	}
      else
	{
	  /* Normal exit, the read request has been fulfilled.  */
	  break;
	}
    }

  dtp->u.p.current_unit->bytes_left -= have_read_record;
  if (unlikely (short_record))
    {
      generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
      return;
    }
  return;
}


/* Function for writing a block of bytes to the current file at the
   current position, advancing the file pointer. We are given a length
   and return a pointer to a buffer that the caller must (completely)
   fill in.  Returns NULL on error.  */

void *
write_block (st_parameter_dt *dtp, size_t length)
{
  char *dest;

  if (!is_stream_io (dtp))
    {
      if (dtp->u.p.current_unit->bytes_left < (gfc_offset) length)
	{
	  /* For preconnected units with default record length, set bytes left
	     to unit record length and proceed, otherwise error.  */
	  if (likely ((dtp->u.p.current_unit->unit_number
		       == options.stdout_unit
		       || dtp->u.p.current_unit->unit_number
		       == options.stderr_unit)
		      && dtp->u.p.current_unit->recl == default_recl))
	    dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
	  else
	    {
	      generate_error (&dtp->common, LIBERROR_EOR, NULL);
	      return NULL;
	    }
	}

      dtp->u.p.current_unit->bytes_left -= (gfc_offset) length;
    }

  if (is_internal_unit (dtp))
    {
      if (is_char4_unit(dtp)) /* char4 internel unit.  */
	{
	  gfc_char4_t *dest4;
	  dest4 = mem_alloc_w4 (dtp->u.p.current_unit->s, &length);
	  if (dest4 == NULL)
	  {
            generate_error (&dtp->common, LIBERROR_END, NULL);
            return NULL;
	  }
	  return dest4;
	}
      else
	dest = mem_alloc_w (dtp->u.p.current_unit->s, &length);

      if (dest == NULL)
	{
          generate_error (&dtp->common, LIBERROR_END, NULL);
          return NULL;
	}

      if (unlikely (dtp->u.p.current_unit->endfile == AT_ENDFILE))
	generate_error (&dtp->common, LIBERROR_END, NULL);
    }
  else
    {
      dest = fbuf_alloc (dtp->u.p.current_unit, length);
      if (dest == NULL)
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return NULL;
	}
    }

  if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
      dtp->u.p.current_unit->has_size)
    dtp->u.p.current_unit->size_used += (GFC_IO_INT) length;

  dtp->u.p.current_unit->strm_pos += (gfc_offset) length;

  return dest;
}


/* High level interface to swrite(), taking care of errors.  This is only
   called for unformatted files.  There are three cases to consider:
   Stream I/O, unformatted direct, unformatted sequential.  */

static bool
write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
{

  ssize_t have_written;
  ssize_t to_write_subrecord;
  int short_record;

  /* Stream I/O.  */

  if (is_stream_io (dtp))
    {
      have_written = swrite (dtp->u.p.current_unit->s, buf, nbytes);
      if (unlikely (have_written < 0))
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return false;
	}

      dtp->u.p.current_unit->strm_pos += (gfc_offset) have_written;

      return true;
    }

  /* Unformatted direct access.  */

  if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
    {
      if (unlikely (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes))
	{
	  generate_error (&dtp->common, LIBERROR_DIRECT_EOR, NULL);
	  return false;
	}

      if (buf == NULL && nbytes == 0)
	return true;

      have_written = swrite (dtp->u.p.current_unit->s, buf, nbytes);
      if (unlikely (have_written < 0))
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return false;
	}

      dtp->u.p.current_unit->strm_pos += (gfc_offset) have_written;
      dtp->u.p.current_unit->bytes_left -= (gfc_offset) have_written;

      return true;
    }

  /* Unformatted sequential.  */

  have_written = 0;

  if (dtp->u.p.current_unit->flags.has_recl
      && (gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left)
    {
      nbytes = dtp->u.p.current_unit->bytes_left;
      short_record = 1;
    }
  else
    {
      short_record = 0;
    }

  while (1)
    {

      to_write_subrecord =
	(size_t) dtp->u.p.current_unit->bytes_left_subrecord < nbytes ?
	(size_t) dtp->u.p.current_unit->bytes_left_subrecord : nbytes;

      dtp->u.p.current_unit->bytes_left_subrecord -=
	(gfc_offset) to_write_subrecord;

      to_write_subrecord = swrite (dtp->u.p.current_unit->s,
				   buf + have_written, to_write_subrecord);
      if (unlikely (to_write_subrecord < 0))
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return false;
	}

      dtp->u.p.current_unit->strm_pos += (gfc_offset) to_write_subrecord;
      nbytes -= to_write_subrecord;
      have_written += to_write_subrecord;

      if (nbytes == 0)
	break;

      next_record_w_unf (dtp, 1);
      us_write (dtp, 1);
    }
  dtp->u.p.current_unit->bytes_left -= have_written;
  if (unlikely (short_record))
    {
      generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
      return false;
    }
  return true;
}


/* Reverse memcpy - used for byte swapping.  */

static void
reverse_memcpy (void *dest, const void *src, size_t n)
{
  char *d, *s;
  size_t i;

  d = (char *) dest;
  s = (char *) src + n - 1;

  /* Write with ascending order - this is likely faster
     on modern architectures because of write combining.  */
  for (i=0; i<n; i++)
      *(d++) = *(s--);
}


/* Utility function for byteswapping an array, using the bswap
   builtins if possible. dest and src can overlap completely, or then
   they must point to separate objects; partial overlaps are not
   allowed.  */

static void
bswap_array (void *dest, const void *src, size_t size, size_t nelems)
{
  const char *ps;
  char *pd;

  switch (size)
    {
    case 1:
      break;
    case 2:
      for (size_t i = 0; i < nelems; i++)
	((uint16_t*)dest)[i] = __builtin_bswap16 (((uint16_t*)src)[i]);
      break;
    case 4:
      for (size_t i = 0; i < nelems; i++)
	((uint32_t*)dest)[i] = __builtin_bswap32 (((uint32_t*)src)[i]);
      break;
    case 8:
      for (size_t i = 0; i < nelems; i++)
	((uint64_t*)dest)[i] = __builtin_bswap64 (((uint64_t*)src)[i]);
      break;
    case 12:
      ps = src;
      pd = dest;
      for (size_t i = 0; i < nelems; i++)
	{
	  uint32_t tmp;
	  memcpy (&tmp, ps, 4);
	  *(uint32_t*)pd = __builtin_bswap32 (*(uint32_t*)(ps + 8));
	  *(uint32_t*)(pd + 4) = __builtin_bswap32 (*(uint32_t*)(ps + 4));
	  *(uint32_t*)(pd + 8) = __builtin_bswap32 (tmp);
	  ps += size;
	  pd += size;
	}
      break;
    case 16:
      ps = src;
      pd = dest;
      for (size_t i = 0; i < nelems; i++)
	{
	  uint64_t tmp;
	  memcpy (&tmp, ps, 8);
	  *(uint64_t*)pd = __builtin_bswap64 (*(uint64_t*)(ps + 8));
	  *(uint64_t*)(pd + 8) = __builtin_bswap64 (tmp);
	  ps += size;
	  pd += size;
	}
      break;
    default:
      pd = dest;
      if (dest != src)
	{
	  ps = src;
	  for (size_t i = 0; i < nelems; i++)
	    {
	      reverse_memcpy (pd, ps, size);
	      ps += size;
	      pd += size;
	    }
	}
      else
	{
	  /* In-place byte swap.  */
	  for (size_t i = 0; i < nelems; i++)
	    {
	      char tmp, *low = pd, *high = pd + size - 1;
	      for (size_t j = 0; j < size/2; j++)
		{
		  tmp = *low;
		  *low = *high;
		  *high = tmp;
		  low++;
		  high--;
		}
	      pd += size;
	    }
	}
    }
}


/* Master function for unformatted reads.  */

static void
unformatted_read (st_parameter_dt *dtp, bt type,
		  void *dest, int kind, size_t size, size_t nelems)
{
  unit_convert convert;

  if (type == BT_CLASS)
    {
	  GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
	  char tmp_iomsg[IOMSG_LEN] = "";
	  char *child_iomsg;
	  gfc_charlen_type child_iomsg_len;
	  GFC_INTEGER_4 noiostat;
	  GFC_INTEGER_4 *child_iostat = NULL;

	  /* Set iostat, intent(out).  */
	  noiostat = 0;
	  child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT)
			  ? dtp->common.iostat : &noiostat);

	  /* Set iomsg, intent(inout).  */
	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
	    {
	      child_iomsg = dtp->common.iomsg;
	      child_iomsg_len = dtp->common.iomsg_len;
	    }
	  else
	    {
	      child_iomsg = tmp_iomsg;
	      child_iomsg_len = IOMSG_LEN;
	    }

	  /* Call the user defined unformatted READ procedure.  */
	  dtp->u.p.current_unit->child_dtio++;
	  dtp->u.p.ufdtio_ptr (dest, &unit, child_iostat, child_iomsg,
			       child_iomsg_len);
	  dtp->u.p.child_saved_iostat = *child_iostat;
	  dtp->u.p.current_unit->child_dtio--;

	  if ((dtp->u.p.child_saved_iostat != 0) &&
	      !(dtp->common.flags & IOPARM_HAS_IOMSG) &&
	      !(dtp->common.flags & IOPARM_HAS_IOSTAT))
	    {
	      char message[IOMSG_LEN + 1];
	      child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg);
	      fstrcpy (message, child_iomsg_len, child_iomsg, child_iomsg_len);
	      message[child_iomsg_len] = '\0';
	      generate_error (&dtp->common, dtp->u.p.child_saved_iostat,
			      message);
	    }

	  return;
    }

  if (type == BT_CHARACTER)
    size *= GFC_SIZE_OF_CHAR_KIND(kind);
  read_block_direct (dtp, dest, size * nelems);

  convert = dtp->u.p.current_unit->flags.convert;
  if (unlikely (convert != GFC_CONVERT_NATIVE) && kind != 1)
    {
      /* Handle wide chracters.  */
      if (type == BT_CHARACTER)
  	{
  	  nelems *= size;
  	  size = kind;
  	}

      /* Break up complex into its constituent reals.  */
      else if (type == BT_COMPLEX)
  	{
  	  nelems *= 2;
  	  size /= 2;
  	}
#ifndef HAVE_GFC_REAL_17
#if defined(HAVE_GFC_REAL_16) && GFC_REAL_16_DIGITS == 106
      /* IBM extended format is stored as a pair of IEEE754
	 double values, with the more significant value first
	 in both big and little endian.  */
      if (kind == 16 && (type == BT_REAL || type == BT_COMPLEX))
	{
	  nelems *= 2;
	  size /= 2;
	}
#endif
      bswap_array (dest, dest, size, nelems);
#else
      unit_convert bswap = convert & ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
      if (bswap == GFC_CONVERT_SWAP)
	{
	  if ((type == BT_REAL || type == BT_COMPLEX)
	      && ((kind == 16 && (convert & GFC_CONVERT_R16_IEEE) == 0)
		  || (kind == 17 && (convert & GFC_CONVERT_R16_IBM))))
	    bswap_array (dest, dest, size / 2, nelems * 2);
	  else
	    bswap_array (dest, dest, size, nelems);
	}

      if ((convert & GFC_CONVERT_R16_IEEE)
	  && kind == 16
	  && (type == BT_REAL || type == BT_COMPLEX))
	{
	  char *pd = dest;
	  for (size_t i = 0; i < nelems; i++)
	    {
	      GFC_REAL_16 r16;
	      GFC_REAL_17 r17;
	      memcpy (&r17, pd, 16);
	      r16 = r17;
	      memcpy (pd, &r16, 16);
	      pd += size;
	    }
	}
      else if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IBM)
	       && kind == 17
	       && (type == BT_REAL || type == BT_COMPLEX))
	{
	  if (type == BT_COMPLEX && size == 32)
	    {
	      nelems *= 2;
	      size /= 2;
	    }

	  char *pd = dest;
	  for (size_t i = 0; i < nelems; i++)
	    {
	      GFC_REAL_16 r16;
	      GFC_REAL_17 r17;
	      memcpy (&r16, pd, 16);
	      r17 = r16;
	      memcpy (pd, &r17, 16);
	      pd += size;
	    }
	}
#endif /* HAVE_GFC_REAL_17.  */
    }
}


/* Master function for unformatted writes.  NOTE: For kind=10 the size is 16
   bytes on 64 bit machines.  The unused bytes are not initialized and never
   used, which can show an error with memory checking analyzers like
   valgrind.  We us BT_CLASS to denote a User Defined I/O call.  */

static void
unformatted_write (st_parameter_dt *dtp, bt type,
		   void *source, int kind, size_t size, size_t nelems)
{
  unit_convert convert;

  if (type == BT_CLASS)
    {
	  GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
	  char tmp_iomsg[IOMSG_LEN] = "";
	  char *child_iomsg;
	  gfc_charlen_type child_iomsg_len;
	  GFC_INTEGER_4 noiostat;
	  GFC_INTEGER_4 *child_iostat = NULL;

	  /* Set iostat, intent(out).  */
	  noiostat = 0;
	  child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT)
			  ? dtp->common.iostat : &noiostat);

	  /* Set iomsg, intent(inout).  */
	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
	    {
	      child_iomsg = dtp->common.iomsg;
	      child_iomsg_len = dtp->common.iomsg_len;
	    }
	  else
	    {
	      child_iomsg = tmp_iomsg;
	      child_iomsg_len = IOMSG_LEN;
	    }

	  /* Call the user defined unformatted WRITE procedure.  */
	  dtp->u.p.current_unit->child_dtio++;
	  dtp->u.p.ufdtio_ptr (source, &unit, child_iostat, child_iomsg,
			       child_iomsg_len);
	  dtp->u.p.child_saved_iostat = *child_iostat;
	  dtp->u.p.current_unit->child_dtio--;

	  if ((dtp->u.p.child_saved_iostat != 0) &&
	      !(dtp->common.flags & IOPARM_HAS_IOMSG) &&
	      !(dtp->common.flags & IOPARM_HAS_IOSTAT))
	    {
	      char message[IOMSG_LEN + 1];
	      child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg);
	      fstrcpy (message, child_iomsg_len, child_iomsg, child_iomsg_len);
	      message[child_iomsg_len] = '\0';
	      generate_error (&dtp->common, dtp->u.p.child_saved_iostat,
			      message);
	    }
	  return;
    }

  convert = dtp->u.p.current_unit->flags.convert;
  if (likely (convert == GFC_CONVERT_NATIVE) || kind == 1
#ifdef HAVE_GFC_REAL_17
      || ((type == BT_REAL || type == BT_COMPLEX)
	  && ((kind == 16 && convert == GFC_CONVERT_R16_IBM)
	      || (kind == 17 && convert == GFC_CONVERT_R16_IEEE)))
#endif
      )
    {
      size_t stride = type == BT_CHARACTER ?
		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;

      write_buf (dtp, source, stride * nelems);
    }
  else
    {
#define BSWAP_BUFSZ 512
      char buffer[BSWAP_BUFSZ];
      char *p;
      size_t nrem;

      p = source;

      /* Handle wide chracters.  */
      if (type == BT_CHARACTER && kind != 1)
	{
	  nelems *= size;
	  size = kind;
	}

      /* Break up complex into its constituent reals.  */
      if (type == BT_COMPLEX)
	{
	  nelems *= 2;
	  size /= 2;
	}

#if !defined(HAVE_GFC_REAL_17) && defined(HAVE_GFC_REAL_16) \
    && GFC_REAL_16_DIGITS == 106
      /* IBM extended format is stored as a pair of IEEE754
	 double values, with the more significant value first
	 in both big and little endian.  */
      if (kind == 16 && (type == BT_REAL || type == BT_COMPLEX))
	{
	  nelems *= 2;
	  size /= 2;
	}
#endif

      /* By now, all complex variables have been split into their
	 constituent reals.  */

      nrem = nelems;
      do
	{
	  size_t nc;
	  if (size * nrem > BSWAP_BUFSZ)
	    nc = BSWAP_BUFSZ / size;
	  else
	    nc = nrem;

#ifdef HAVE_GFC_REAL_17
	  if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IEEE)
	      && kind == 16
	      && (type == BT_REAL || type == BT_COMPLEX))
	    {
	      for (size_t i = 0; i < nc; i++)
		{
		  GFC_REAL_16 r16;
		  GFC_REAL_17 r17;
		  memcpy (&r16, p, 16);
		  r17 = r16;
		  memcpy (&buffer[i * 16], &r17, 16);
		  p += 16;
		}
	      if ((dtp->u.p.current_unit->flags.convert
		   & ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM))
		  == GFC_CONVERT_SWAP)
		bswap_array (buffer, buffer, size, nc);
	    }
	  else if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IBM)
		   && kind == 17
		   && (type == BT_REAL || type == BT_COMPLEX))
	    {
	      for (size_t i = 0; i < nc; i++)
		{
		  GFC_REAL_16 r16;
		  GFC_REAL_17 r17;
		  memcpy (&r17, p, 16);
		  r16 = r17;
		  memcpy (&buffer[i * 16], &r16, 16);
		  p += 16;
		}
	      if ((dtp->u.p.current_unit->flags.convert
		   & ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM))
		  == GFC_CONVERT_SWAP)
		bswap_array (buffer, buffer, size / 2, nc * 2);
	    }
	  else if (kind == 16 && (type == BT_REAL || type == BT_COMPLEX))
	    {
	      bswap_array (buffer, p, size / 2, nc * 2);
	      p += size * nc;
	    }
	  else
#endif
	    {
	      bswap_array (buffer, p, size, nc);
	      p += size * nc;
	    }
	  write_buf (dtp, buffer, size * nc);
	  nrem -= nc;
	}
      while (nrem > 0);
    }
}


/* Return a pointer to the name of a type.  */

const char *
type_name (bt type)
{
  const char *p;

  switch (type)
    {
    case BT_INTEGER:
      p = "INTEGER";
      break;
    case BT_UNSIGNED:
      p = "UNSIGNED";
      break;
    case BT_LOGICAL:
      p = "LOGICAL";
      break;
    case BT_CHARACTER:
      p = "CHARACTER";
      break;
    case BT_REAL:
      p = "REAL";
      break;
    case BT_COMPLEX:
      p = "COMPLEX";
      break;
    case BT_CLASS:
      p = "CLASS or DERIVED";
      break;
    default:
      internal_error (NULL, "type_name(): Bad type");
    }

  return p;
}


/* Write a constant string to the output.
   This is complicated because the string can have doubled delimiters
   in it.  The length in the format node is the true length.  */

static void
write_constant_string (st_parameter_dt *dtp, const fnode *f)
{
  char c, delimiter, *p, *q;
  int length;

  length = f->u.string.length;
  if (length == 0)
    return;

  p = write_block (dtp, length);
  if (p == NULL)
    return;

  q = f->u.string.p;
  delimiter = q[-1];

  for (; length > 0; length--)
    {
      c = *p++ = *q++;
      if (c == delimiter && c != 'H' && c != 'h')
	q++;			/* Skip the doubled delimiter.  */
    }
}


/* Given actual and expected types in a formatted data transfer, make
   sure they agree.  If not, an error message is generated.  Returns
   nonzero if something went wrong.  */

static int
require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
{
#define BUFLEN 100
  char buffer[BUFLEN];

  if (actual == expected)
    return 0;

  /* Adjust item_count before emitting error message.  */
  snprintf (buffer, BUFLEN,
	    "Expected %s for item %d in formatted transfer, got %s",
	   type_name (expected), dtp->u.p.item_count - 1, type_name (actual));

  format_error (dtp, f, buffer);
  return 1;
}

/* Check that the actual matches one of two expected types; issue an error
   if that is not the case.  */


static int
require_one_of_two_types (st_parameter_dt *dtp, bt expected1, bt expected2,
			  bt actual, const fnode *f)
{
  char buffer[BUFLEN];

  if (actual == expected1)
    return 0;

  if (actual == expected2)
    return 0;

  snprintf (buffer, BUFLEN,
	    "Expected %s or %s for item %d in formatted transfer, got %s",
	    type_name (expected1), type_name (expected2),
	    dtp->u.p.item_count - 1, type_name (actual));

  format_error (dtp, f, buffer);
  return 1;

}

/* Check that the dtio procedure required for formatted IO is present.  */

static int
check_dtio_proc (st_parameter_dt *dtp, const fnode *f)
{
  char buffer[BUFLEN];

  if (dtp->u.p.fdtio_ptr != NULL)
    return 0;

  snprintf (buffer, BUFLEN,
	    "Missing DTIO procedure or intrinsic type passed for item %d "
	    "in formatted transfer",
	    dtp->u.p.item_count - 1);

  format_error (dtp, f, buffer);
  return 1;
}


static int
require_numeric_type (st_parameter_dt *dtp, bt actual, const fnode *f)
{
#define BUFLEN 100
  char buffer[BUFLEN];

  if (actual == BT_INTEGER || actual == BT_REAL || actual == BT_COMPLEX)
    return 0;

  /* Adjust item_count before emitting error message.  */
  snprintf (buffer, BUFLEN,
	    "Expected numeric type for item %d in formatted transfer, got %s",
	    dtp->u.p.item_count - 1, type_name (actual));

  format_error (dtp, f, buffer);
  return 1;
}

static char *
get_dt_format (char *p, gfc_charlen_type *length)
{
  char delim = p[-1];  /* The delimiter is always the first character back.  */
  char c, *q, *res;
  gfc_charlen_type len = *length; /* This length already correct, less 'DT'.  */

  res = q = xmalloc (len + 2);

  /* Set the beginning of the string to 'DT', length adjusted below.  */
  *q++ = 'D';
  *q++ = 'T';

  /* The string may contain doubled quotes so scan and skip as needed.  */
  for (; len > 0; len--)
    {
      c = *q++ = *p++;
      if (c == delim)
	p++;  /* Skip the doubled delimiter.  */
    }

  /* Adjust the string length by two now that we are done.  */
  *length += 2;

  return res;
}


/* This function is in the main loop for a formatted data transfer
   statement.  It would be natural to implement this as a coroutine
   with the user program, but C makes that awkward.  We loop,
   processing format elements.  When we actually have to transfer
   data instead of just setting flags, we return control to the user
   program which calls a function that supplies the address and type
   of the next element, then comes back here to process it.  */

static void
formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind,
				size_t size)
{
  int pos, bytes_used;
  const fnode *f;
  format_token t;
  int n;
  int consume_data_flag;

  /* Change a complex data item into a pair of reals.  */

  n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
  if (type == BT_COMPLEX)
    {
      type = BT_REAL;
      size /= 2;
    }

  /* If there's an EOR condition, we simulate finalizing the transfer
     by doing nothing.  */
  if (dtp->u.p.eor_condition)
    return;

  /* Set this flag so that commas in reads cause the read to complete before
     the entire field has been read.  The next read field will start right after
     the comma in the stream.  (Set to 0 for character reads).  */
  dtp->u.p.sf_read_comma =
    dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;

  for (;;)
    {
      /* If reversion has occurred and there is another real data item,
	 then we have to move to the next record.  */
      if (dtp->u.p.reversion_flag && n > 0)
	{
	  dtp->u.p.reversion_flag = 0;
	  next_record (dtp, 0);
	}

      consume_data_flag = 1;
      if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
	break;

      f = next_format (dtp);
      if (f == NULL)
	{
	  /* No data descriptors left.  */
	  if (unlikely (n > 0))
	    generate_error (&dtp->common, LIBERROR_FORMAT,
		"Insufficient data descriptors in format after reversion");
	  return;
	}

      t = f->format;

      bytes_used = (int)(dtp->u.p.current_unit->recl
		   - dtp->u.p.current_unit->bytes_left);

      if (is_stream_io(dtp))
	bytes_used = 0;

      switch (t)
	{
	case FMT_I:
	  if (n == 0)
	    goto need_read_data;
	  if (require_one_of_two_types (dtp, BT_INTEGER, BT_UNSIGNED, type, f))
	    return;
	  if (type == BT_INTEGER)
	    read_decimal (dtp, f, p, kind);
	  else
	    read_decimal_unsigned (dtp, f, p, kind);
	  break;

	case FMT_B:
	  if (n == 0)
	    goto need_read_data;
	  if (!(compile_options.allow_std & GFC_STD_GNU)
	      && require_numeric_type (dtp, type, f))
	    return;
	  if (!(compile_options.allow_std & GFC_STD_F2008)
              && require_type (dtp, BT_INTEGER, type, f))
	    return;
#ifdef HAVE_GFC_REAL_17
	  if (type == BT_REAL && kind == 17)
	    kind = 16;
#endif
	  read_radix (dtp, f, p, kind, 2);
	  break;

	case FMT_O:
	  if (n == 0)
	    goto need_read_data;
	  if (!(compile_options.allow_std & GFC_STD_GNU)
	      && require_numeric_type (dtp, type, f))
	    return;
	  if (!(compile_options.allow_std & GFC_STD_F2008)
              && require_type (dtp, BT_INTEGER, type, f))
	    return;
#ifdef HAVE_GFC_REAL_17
	  if (type == BT_REAL && kind == 17)
	    kind = 16;
#endif
	  read_radix (dtp, f, p, kind, 8);
	  break;

	case FMT_Z:
	  if (n == 0)
	    goto need_read_data;
	  if (!(compile_options.allow_std & GFC_STD_GNU)
	      && require_numeric_type (dtp, type, f))
	    return;
	  if (!(compile_options.allow_std & GFC_STD_F2008)
              && require_type (dtp, BT_INTEGER, type, f))
	    return;
#ifdef HAVE_GFC_REAL_17
	  if (type == BT_REAL && kind == 17)
	    kind = 16;
#endif
	  read_radix (dtp, f, p, kind, 16);
	  break;

	case FMT_A:
	  if (n == 0)
	    goto need_read_data;

	  /* It is possible to have FMT_A with something not BT_CHARACTER such
	     as when writing out hollerith strings, so check both type
	     and kind before calling wide character routines.  */
	  if (type == BT_CHARACTER && kind == 4)
	    read_a_char4 (dtp, f, p, size);
	  else
	    read_a (dtp, f, p, size);
	  break;

	case FMT_L:
	  if (n == 0)
	    goto need_read_data;
	  read_l (dtp, f, p, kind);
	  break;

	case FMT_D:
	  if (n == 0)
	    goto need_read_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  read_f (dtp, f, p, kind);
	  break;

	case FMT_DT:
	  if (n == 0)
	    goto need_read_data;

	  if (check_dtio_proc (dtp, f))
	    return;
	  if (require_type (dtp, BT_CLASS, type, f))
	    return;
	  GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
	  char dt[] = "DT";
	  char tmp_iomsg[IOMSG_LEN] = "";
	  char *child_iomsg;
	  gfc_charlen_type child_iomsg_len;
	  GFC_INTEGER_4 noiostat;
	  GFC_INTEGER_4 *child_iostat = NULL;
	  char *iotype;
	  gfc_charlen_type iotype_len = f->u.udf.string_len;

	  /* Build the iotype string.  */
	  if (iotype_len == 0)
	    {
	      iotype_len = 2;
	      iotype = dt;
	    }
	  else
	    iotype = get_dt_format (f->u.udf.string, &iotype_len);

	  /* Set iostat, intent(out).  */
	  noiostat = 0;
	  child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT)
			  ? dtp->common.iostat : &noiostat);

	  /* Set iomsg, intent(inout).  */
	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
	    {
	      child_iomsg = dtp->common.iomsg;
	      child_iomsg_len = dtp->common.iomsg_len;
	    }
	  else
	    {
	      child_iomsg = tmp_iomsg;
	      child_iomsg_len = IOMSG_LEN;
	    }

	  /* Call the user defined formatted READ procedure.  */
	  dtp->u.p.current_unit->child_dtio++;
	  dtp->u.p.current_unit->last_char = EOF - 1;
	  dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
			      child_iostat, child_iomsg,
			      iotype_len, child_iomsg_len);
	  dtp->u.p.child_saved_iostat = *child_iostat;
	  dtp->u.p.current_unit->child_dtio--;

	  if ((dtp->u.p.child_saved_iostat != 0) &&
	      !(dtp->common.flags & IOPARM_HAS_IOMSG) &&
	      !(dtp->common.flags & IOPARM_HAS_IOSTAT))
	    {
	      char message[IOMSG_LEN + 1];
	      child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg);
	      fstrcpy (message, child_iomsg_len, child_iomsg, child_iomsg_len);
	      message[child_iomsg_len] = '\0';
	      generate_error (&dtp->common, dtp->u.p.child_saved_iostat,
			      message);
	    }

	  if (f->u.udf.string_len != 0)
	    free (iotype);
	  /* Note: vlist is freed in free_format_data.  */
	  break;

	case FMT_E:
	  if (n == 0)
	    goto need_read_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  read_f (dtp, f, p, kind);
	  break;

	case FMT_EN:
	  if (n == 0)
	    goto need_read_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  read_f (dtp, f, p, kind);
	  break;

	case FMT_ES:
	  if (n == 0)
	    goto need_read_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  read_f (dtp, f, p, kind);
	  break;

	case FMT_F:
	  if (n == 0)
	    goto need_read_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  read_f (dtp, f, p, kind);
	  break;

	case FMT_G:
	  if (n == 0)
	    goto need_read_data;
	  switch (type)
	    {
	      case BT_INTEGER:
		read_decimal (dtp, f, p, kind);
		break;
	      case BT_LOGICAL:
		read_l (dtp, f, p, kind);
		break;
	      case BT_CHARACTER:
		if (kind == 4)
		  read_a_char4 (dtp, f, p, size);
		else
		  read_a (dtp, f, p, size);
		break;
	      case BT_REAL:
		read_f (dtp, f, p, kind);
		break;
	      default:
		internal_error (&dtp->common,
				"formatted_transfer (): Bad type");
	    }
	  break;

	case FMT_STRING:
	  consume_data_flag = 0;
	  format_error (dtp, f, "Constant string in input format");
	  return;

	/* Format codes that don't transfer data.  */
	case FMT_X:
	case FMT_TR:
	  consume_data_flag = 0;
	  dtp->u.p.skips += f->u.n;
	  pos = bytes_used + dtp->u.p.skips - 1;
	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
	  read_x (dtp, f->u.n);
	  break;

	case FMT_TL:
	case FMT_T:
	  consume_data_flag = 0;

	  if (f->format == FMT_TL)
	    {
	      /* Handle the special case when no bytes have been used yet.
	         Cannot go below zero. */
	      if (bytes_used == 0)
		{
		  dtp->u.p.pending_spaces -= f->u.n;
		  dtp->u.p.skips -= f->u.n;
		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
		}

	      pos = bytes_used - f->u.n;
	    }
	  else /* FMT_T */
	    pos = f->u.n - 1;

	  /* Standard 10.6.1.1: excessive left tabbing is reset to the
	     left tab limit.  We do not check if the position has gone
	     beyond the end of record because a subsequent tab could
	     bring us back again.  */
	  pos = pos < 0 ? 0 : pos;

	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
				    + pos - dtp->u.p.max_pos;
	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
				    ? 0 : dtp->u.p.pending_spaces;
	  if (dtp->u.p.skips == 0)
	    break;

	  /* Adjust everything for end-of-record condition */
	  if (dtp->u.p.sf_seen_eor && !is_internal_unit (dtp))
	    {
              dtp->u.p.current_unit->bytes_left -= dtp->u.p.sf_seen_eor;
              dtp->u.p.skips -= dtp->u.p.sf_seen_eor;
	      bytes_used = pos;
	      if (dtp->u.p.pending_spaces == 0)
		dtp->u.p.sf_seen_eor = 0;
	    }
	  if (dtp->u.p.skips < 0)
	    {
              if (is_internal_unit (dtp))
                sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
              else
                fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
	      dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
	      dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
	    }
	  else
	    read_x (dtp, dtp->u.p.skips);
	  break;

	case FMT_S:
	  consume_data_flag = 0;
	  dtp->u.p.sign_status = SIGN_PROCDEFINED;
	  break;

	case FMT_SS:
	  consume_data_flag = 0;
	  dtp->u.p.sign_status = SIGN_SUPPRESS;
	  break;

	case FMT_SP:
	  consume_data_flag = 0;
	  dtp->u.p.sign_status = SIGN_PLUS;
	  break;

	case FMT_BN:
	  consume_data_flag = 0 ;
	  dtp->u.p.blank_status = BLANK_NULL;
	  break;

	case FMT_BZ:
	  consume_data_flag = 0;
	  dtp->u.p.blank_status = BLANK_ZERO;
	  break;

	case FMT_DC:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
	  break;

	case FMT_DP:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
	  break;

	case FMT_RC:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
	  break;

	case FMT_RD:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_DOWN;
	  break;

	case FMT_RN:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_NEAREST;
	  break;

	case FMT_RP:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
	  break;

	case FMT_RU:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_UP;
	  break;

	case FMT_RZ:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_ZERO;
	  break;

	case FMT_P:
	  consume_data_flag = 0;
	  dtp->u.p.scale_factor = f->u.k;
	  break;

	case FMT_DOLLAR:
	  consume_data_flag = 0;
	  dtp->u.p.seen_dollar = 1;
	  break;

	case FMT_SLASH:
	  consume_data_flag = 0;
	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
	  next_record (dtp, 0);
	  break;

	case FMT_COLON:
	  /* A colon descriptor causes us to exit this loop (in
	     particular preventing another / descriptor from being
	     processed) unless there is another data item to be
	     transferred.  */
	  consume_data_flag = 0;
	  if (n == 0)
	    return;
	  break;

	default:
	  internal_error (&dtp->common, "Bad format node");
	}

      /* Adjust the item count and data pointer.  */

      if ((consume_data_flag > 0) && (n > 0))
	{
	  n--;
	  p = ((char *) p) + size;
	}

      dtp->u.p.skips = 0;

      pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
      dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
    }

  return;

  /* Come here when we need a data descriptor but don't have one.  We
     push the current format node back onto the input, then return and
     let the user program call us back with the data.  */
 need_read_data:
  unget_format (dtp, f);
}


static void
formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind,
				 size_t size)
{
  gfc_offset tab_pos, bytes_used;
  const fnode *f;
  format_token t;
  int n;
  int consume_data_flag;

  tab_pos = 0; bytes_used = 0;

  /* Change a complex data item into a pair of reals.  */

  n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
  if (type == BT_COMPLEX)
    {
      type = BT_REAL;
      size /= 2;
    }

  /* If there's an EOR condition, we simulate finalizing the transfer
     by doing nothing.  */
  if (dtp->u.p.eor_condition)
    return;

  /* Set this flag so that commas in reads cause the read to complete before
     the entire field has been read.  The next read field will start right after
     the comma in the stream.  (Set to 0 for character reads).  */
  dtp->u.p.sf_read_comma =
    dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;

  for (;;)
    {
      /* If reversion has occurred and there is another real data item,
	 then we have to move to the next record.  */
      if (dtp->u.p.reversion_flag && n > 0)
	{
	  dtp->u.p.reversion_flag = 0;
	  next_record (dtp, 0);
	}

      consume_data_flag = 1;
      if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
	break;

      f = next_format (dtp);
      if (f == NULL)
	{
	  /* No data descriptors left.  */
	  if (unlikely (n > 0))
	    generate_error (&dtp->common, LIBERROR_FORMAT,
		"Insufficient data descriptors in format after reversion");
	  return;
	}

      /* Now discharge T, TR and X movements to the right.  This is delayed
	 until a data producing format to suppress trailing spaces.  */

      t = f->format;
      if (dtp->u.p.mode == WRITING && dtp->u.p.skips != 0
	&& ((n>0 && (  t == FMT_I  || t == FMT_B  || t == FMT_O
		    || t == FMT_Z  || t == FMT_F  || t == FMT_E
		    || t == FMT_EN || t == FMT_ES || t == FMT_G
		    || t == FMT_L  || t == FMT_A  || t == FMT_D
		    || t == FMT_DT))
	    || t == FMT_STRING))
	{
	  if (dtp->u.p.skips > 0)
	    {
	      gfc_offset tmp;
	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
	      tmp = dtp->u.p.current_unit->recl
			  - dtp->u.p.current_unit->bytes_left;
	      dtp->u.p.max_pos =
		dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
	      dtp->u.p.skips = 0;
	    }
	  if (dtp->u.p.skips < 0)
	    {
              if (is_internal_unit (dtp))
	        sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
              else
                fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
	      dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
	    }
	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
	}

      if (is_stream_io(dtp))
	bytes_used = dtp->u.p.current_unit->fbuf->act;
      else
	bytes_used = dtp->u.p.current_unit->recl
		    - dtp->u.p.current_unit->bytes_left;

      switch (t)
	{
	case FMT_I:
	  if (n == 0)
	    goto need_data;
	  if (require_one_of_two_types (dtp, BT_INTEGER, BT_UNSIGNED, type, f))
	    return;
	  if (type == BT_INTEGER)
	    write_i (dtp, f, p, kind);
	  else
	    write_iu (dtp, f, p, kind);
	  break;

	case FMT_B:
	  if (n == 0)
	    goto need_data;
	  if (!(compile_options.allow_std & GFC_STD_GNU)
	      && require_numeric_type (dtp, type, f))
	    return;
	  if (!(compile_options.allow_std & GFC_STD_F2008)
              && require_type (dtp, BT_INTEGER, type, f))
	    return;
#ifdef HAVE_GFC_REAL_17
	  if (type == BT_REAL && kind == 17)
	    kind = 16;
#endif
	  write_b (dtp, f, p, kind);
	  break;

	case FMT_O:
	  if (n == 0)
	    goto need_data;
	  if (!(compile_options.allow_std & GFC_STD_GNU)
	      && require_numeric_type (dtp, type, f))
	    return;
	  if (!(compile_options.allow_std & GFC_STD_F2008)
              && require_type (dtp, BT_INTEGER, type, f))
	    return;
#ifdef HAVE_GFC_REAL_17
	  if (type == BT_REAL && kind == 17)
	    kind = 16;
#endif
	  write_o (dtp, f, p, kind);
	  break;

	case FMT_Z:
	  if (n == 0)
	    goto need_data;
	  if (!(compile_options.allow_std & GFC_STD_GNU)
	      && require_numeric_type (dtp, type, f))
	    return;
	  if (!(compile_options.allow_std & GFC_STD_F2008)
              && require_type (dtp, BT_INTEGER, type, f))
	    return;
#ifdef HAVE_GFC_REAL_17
	  if (type == BT_REAL && kind == 17)
	    kind = 16;
#endif
	  write_z (dtp, f, p, kind);
	  break;

	case FMT_A:
	  if (n == 0)
	    goto need_data;

	  /* It is possible to have FMT_A with something not BT_CHARACTER such
	     as when writing out hollerith strings, so check both type
	     and kind before calling wide character routines.  */
	  if (type == BT_CHARACTER && kind == 4)
	    write_a_char4 (dtp, f, p, size);
	  else
	    write_a (dtp, f, p, size);
	  break;

	case FMT_L:
	  if (n == 0)
	    goto need_data;
	  write_l (dtp, f, p, kind);
	  break;

	case FMT_D:
	  if (n == 0)
	    goto need_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  if (f->u.real.w == 0)
	    write_real_w0 (dtp, p, kind, f);
	  else
	    write_d (dtp, f, p, kind);
	  break;

	case FMT_DT:
	  if (n == 0)
	    goto need_data;
	  GFC_INTEGER_4 unit = dtp->u.p.current_unit->unit_number;
	  char dt[] = "DT";
	  char tmp_iomsg[IOMSG_LEN] = "";
	  char *child_iomsg;
	  gfc_charlen_type child_iomsg_len;
	  GFC_INTEGER_4 noiostat;
	  GFC_INTEGER_4 *child_iostat = NULL;
	  char *iotype;
	  gfc_charlen_type iotype_len = f->u.udf.string_len;

	  /* Build the iotype string.  */
	  if (iotype_len == 0)
	    {
	      iotype_len = 2;
	      iotype = dt;
	    }
	  else
	    iotype = get_dt_format (f->u.udf.string, &iotype_len);

	  /* Set iostat, intent(out).  */
	  noiostat = 0;
	  child_iostat = ((dtp->common.flags & IOPARM_HAS_IOSTAT)
			  ? dtp->common.iostat : &noiostat);

	  /* Set iomsg, intent(inout).  */
	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
	    {
	      child_iomsg = dtp->common.iomsg;
	      child_iomsg_len = dtp->common.iomsg_len;
	    }
	  else
	    {
	      child_iomsg = tmp_iomsg;
	      child_iomsg_len = IOMSG_LEN;
	    }

	  if (check_dtio_proc (dtp, f))
	    return;

	  /* Call the user defined formatted WRITE procedure.  */
	  dtp->u.p.current_unit->child_dtio++;

	  dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
			      child_iostat, child_iomsg,
			      iotype_len, child_iomsg_len);
	  dtp->u.p.child_saved_iostat = *child_iostat;
	  dtp->u.p.current_unit->child_dtio--;

	  if ((dtp->u.p.child_saved_iostat != 0) &&
	      !(dtp->common.flags & IOPARM_HAS_IOMSG) &&
	      !(dtp->common.flags & IOPARM_HAS_IOSTAT))
	    {
	      char message[IOMSG_LEN + 1];
	      child_iomsg_len = string_len_trim (IOMSG_LEN, child_iomsg);
	      fstrcpy (message, child_iomsg_len, child_iomsg, child_iomsg_len);
	      message[child_iomsg_len] = '\0';
	      generate_error (&dtp->common, dtp->u.p.child_saved_iostat,
			      message);
	    }

	  if (f->u.udf.string_len != 0)
	    free (iotype);
	  /* Note: vlist is freed in free_format_data.  */
	  break;

	case FMT_E:
	  if (n == 0)
	    goto need_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  if (f->u.real.w == 0)
	    write_real_w0 (dtp, p, kind, f);
	  else
	    write_e (dtp, f, p, kind);
	  break;

	case FMT_EN:
	  if (n == 0)
	    goto need_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  if (f->u.real.w == 0)
	    write_real_w0 (dtp, p, kind, f);
	  else
	    write_en (dtp, f, p, kind);
	  break;

	case FMT_ES:
	  if (n == 0)
	    goto need_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  if (f->u.real.w == 0)
	    write_real_w0 (dtp, p, kind, f);
	  else
	    write_es (dtp, f, p, kind);
	  break;

	case FMT_F:
	  if (n == 0)
	    goto need_data;
	  if (require_type (dtp, BT_REAL, type, f))
	    return;
	  write_f (dtp, f, p, kind);
	  break;

	case FMT_G:
	  if (n == 0)
	    goto need_data;
	  switch (type)
	    {
	      case BT_INTEGER:
		write_i (dtp, f, p, kind);
		break;
	      case BT_UNSIGNED:
		write_iu (dtp, f, p, kind);
		break;
	      case BT_LOGICAL:
		write_l (dtp, f, p, kind);
		break;
	      case BT_CHARACTER:
		if (kind == 4)
		  write_a_char4 (dtp, f, p, size);
		else
		  write_a (dtp, f, p, size);
		break;
	      case BT_REAL:
		if (f->u.real.w == 0)
		  write_real_w0 (dtp, p, kind, f);
		else
		  write_d (dtp, f, p, kind);
		break;
	      default:
		internal_error (&dtp->common,
				"formatted_transfer (): Bad type");
	    }
	  break;

	case FMT_STRING:
	  consume_data_flag = 0;
	  write_constant_string (dtp, f);
	  break;

	/* Format codes that don't transfer data.  */
	case FMT_X:
	case FMT_TR:
	  consume_data_flag = 0;
	  dtp->u.p.skips += f->u.n;
	  tab_pos = bytes_used + dtp->u.p.skips - 1;
	  dtp->u.p.pending_spaces = tab_pos - dtp->u.p.max_pos + 1;
	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
				    ? f->u.n : dtp->u.p.pending_spaces;

	  /* Writes occur just before the switch on f->format, above, so
	     that trailing blanks are suppressed, unless we are doing a
	     non-advancing write in which case we want to output the blanks
	     now.  */
	  if (dtp->u.p.advance_status == ADVANCE_NO)
	    {
	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
	      dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
	    }
	  break;

	case FMT_TL:
	  consume_data_flag = 0;
	  /* Handle the special case when no bytes have been used yet.
	     Cannot go below zero. */
	  if (bytes_used == 0)
	    {
	      dtp->u.p.pending_spaces -= f->u.n;
	      dtp->u.p.skips -= f->u.n;
	      dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
	    }

	  tab_pos = bytes_used - f->u.n;

	  /* Standard 10.6.1.1: excessive left tabbing is reset to the
	     left tab limit.  We do not check if the position has gone
	     beyond the end of record because a subsequent tab could
	     bring us back again.  */
	  tab_pos = tab_pos < 0 ? 0 : tab_pos;

	  dtp->u.p.skips = dtp->u.p.skips + tab_pos - bytes_used;
	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
				    + tab_pos - dtp->u.p.max_pos;
	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
				    ? 0 : dtp->u.p.pending_spaces;
	  break;

	case FMT_T:
	  consume_data_flag = 0;
	  if (f->u.n < tab_pos + 1)
	    {
	      tab_pos = f->u.n;
	      dtp->u.p.skips = tab_pos - bytes_used - 1;
	      dtp->u.p.pending_spaces = tab_pos - bytes_used - 1;
	    }
	  else
	    {
	      tab_pos = f->u.n - dtp->u.p.pending_spaces - 1;

	      /* Excessive left tabbing is reset to the left tab limit.  */
	      tab_pos = tab_pos < 0 ? 0 : tab_pos;

	      dtp->u.p.skips = dtp->u.p.skips + tab_pos - bytes_used;
	      dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
				      + tab_pos - dtp->u.p.max_pos;
	    }
	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
				    ? 0 : dtp->u.p.pending_spaces;
	  break;

	case FMT_S:
	  consume_data_flag = 0;
	  dtp->u.p.sign_status = SIGN_PROCDEFINED;
	  break;

	case FMT_SS:
	  consume_data_flag = 0;
	  dtp->u.p.sign_status = SIGN_SUPPRESS;
	  break;

	case FMT_SP:
	  consume_data_flag = 0;
	  dtp->u.p.sign_status = SIGN_PLUS;
	  break;

	case FMT_BN:
	  consume_data_flag = 0 ;
	  dtp->u.p.blank_status = BLANK_NULL;
	  break;

	case FMT_BZ:
	  consume_data_flag = 0;
	  dtp->u.p.blank_status = BLANK_ZERO;
	  break;

	case FMT_DC:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
	  break;

	case FMT_DP:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
	  break;

	case FMT_RC:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
	  break;

	case FMT_RD:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_DOWN;
	  break;

	case FMT_RN:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_NEAREST;
	  break;

	case FMT_RP:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
	  break;

	case FMT_RU:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_UP;
	  break;

	case FMT_RZ:
	  consume_data_flag = 0;
	  dtp->u.p.current_unit->round_status = ROUND_ZERO;
	  break;

	case FMT_P:
	  consume_data_flag = 0;
	  dtp->u.p.scale_factor = f->u.k;
	  break;

	case FMT_DOLLAR:
	  consume_data_flag = 0;
	  dtp->u.p.seen_dollar = 1;
	  break;

	case FMT_SLASH:
	  consume_data_flag = 0;
	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
	  next_record (dtp, 0);
	  break;

	case FMT_COLON:
	  /* A colon descriptor causes us to exit this loop (in
	     particular preventing another / descriptor from being
	     processed) unless there is another data item to be
	     transferred.  */
	  consume_data_flag = 0;
	  if (n == 0)
	    return;
	  break;

	default:
	  internal_error (&dtp->common, "Bad format node");
	}

      /* Adjust the item count and data pointer.  */

      if ((consume_data_flag > 0) && (n > 0))
	{
	  n--;
	  p = ((char *) p) + size;
	}

      /* Calculate the new max_pos if any.  */
      gfc_offset new_pos;
      if (is_stream_io(dtp))
	new_pos = dtp->u.p.current_unit->fbuf->act;
      else
	new_pos = dtp->u.p.current_unit->recl
		   - dtp->u.p.current_unit->bytes_left;

      dtp->u.p.max_pos = (dtp->u.p.max_pos > new_pos) ?
			  dtp->u.p.max_pos : new_pos;
    }

  return;

  /* Come here when we need a data descriptor but don't have one.  We
     push the current format node back onto the input, then return and
     let the user program call us back with the data.  */
 need_data:
  unget_format (dtp, f);
}

  /* This function is first called from data_init_transfer to initiate the loop
     over each item in the format, transferring data as required.  Subsequent
     calls to this function occur for each data item foound in the READ/WRITE
     statement.  The item_count is incremented for each call.  Since the first
     call is from data_transfer_init, the item_count is always one greater than
     the actual count number of the item being transferred.  */

static void
formatted_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
		    size_t size, size_t nelems)
{
  size_t elem;
  char *tmp;

  tmp = (char *) p;
  size_t stride = type == BT_CHARACTER ?
		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
  if (dtp->u.p.mode == READING)
    {
      /* Big loop over all the elements.  */
      for (elem = 0; elem < nelems; elem++)
	{
	  dtp->u.p.item_count++;
	  formatted_transfer_scalar_read (dtp, type, tmp + stride*elem, kind, size);
	}
    }
  else
    {
      /* Big loop over all the elements.  */
      for (elem = 0; elem < nelems; elem++)
	{
	  dtp->u.p.item_count++;
	  formatted_transfer_scalar_write (dtp, type, tmp + stride*elem, kind, size);
	}
    }
}

/* Wrapper function for I/O of scalar types.  If this should be an async I/O
   request, queue it.  For a synchronous write on an async unit, perform the
   wait operation and return an error.  For all synchronous writes, call the
   right transfer function.  */

static void
wrap_scalar_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
		      size_t size, size_t n_elem)
{
  if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
    {
      if (dtp->u.p.async)
	{
	  transfer_args args;
	  args.scalar.transfer = dtp->u.p.transfer;
	  args.scalar.arg_bt = type;
	  args.scalar.data = p;
	  args.scalar.i = kind;
	  args.scalar.s1 = size;
	  args.scalar.s2 = n_elem;
	  enqueue_transfer (dtp->u.p.current_unit->au, &args,
			    AIO_TRANSFER_SCALAR);
	  return;
	}
    }
  /* Come here if there was no asynchronous I/O to be scheduled.  */
  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;

  dtp->u.p.transfer (dtp, type, p, kind, size, 1);
}


/* Data transfer entry points.  The type of the data entity is
   implicit in the subroutine call.  This prevents us from having to
   share a common enum with the compiler.  */

void
transfer_integer (st_parameter_dt *dtp, void *p, int kind)
{
    wrap_scalar_transfer (dtp, BT_INTEGER, p, kind, kind, 1);
}

void
transfer_integer_write (st_parameter_dt *dtp, void *p, int kind)
{
  transfer_integer (dtp, p, kind);
}

void
transfer_unsigned (st_parameter_dt *dtp, void *p, int kind)
{
    wrap_scalar_transfer (dtp, BT_UNSIGNED, p, kind, kind, 1);
}

void
transfer_unsigned_write (st_parameter_dt *dtp, void *p, int kind)
{
  transfer_unsigned (dtp, p, kind);
}

void
transfer_real (st_parameter_dt *dtp, void *p, int kind)
{
  size_t size;
  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;
  size = size_from_real_kind (kind);
  wrap_scalar_transfer (dtp, BT_REAL, p, kind, size, 1);
}

void
transfer_real_write (st_parameter_dt *dtp, void *p, int kind)
{
  transfer_real (dtp, p, kind);
}

void
transfer_logical (st_parameter_dt *dtp, void *p, int kind)
{
  wrap_scalar_transfer (dtp, BT_LOGICAL, p, kind, kind, 1);
}

void
transfer_logical_write (st_parameter_dt *dtp, void *p, int kind)
{
  transfer_logical (dtp, p, kind);
}

void
transfer_character (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
{
  static char *empty_string[0];

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;

  /* Strings of zero length can have p == NULL, which confuses the
     transfer routines into thinking we need more data elements.  To avoid
     this, we give them a nice pointer.  */
  if (len == 0 && p == NULL)
    p = empty_string;

  /* Set kind here to 1.  */
  wrap_scalar_transfer (dtp, BT_CHARACTER, p, 1, len, 1);
}

void
transfer_character_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
{
  transfer_character (dtp, p, len);
}

void
transfer_character_wide (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
{
  static char *empty_string[0];

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;

  /* Strings of zero length can have p == NULL, which confuses the
     transfer routines into thinking we need more data elements.  To avoid
     this, we give them a nice pointer.  */
  if (len == 0 && p == NULL)
    p = empty_string;

  /* Here we pass the actual kind value.  */
  wrap_scalar_transfer (dtp, BT_CHARACTER, p, kind, len, 1);
}

void
transfer_character_wide_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
{
  transfer_character_wide (dtp, p, len, kind);
}

void
transfer_complex (st_parameter_dt *dtp, void *p, int kind)
{
  size_t size;
  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;
  size = size_from_complex_kind (kind);
  wrap_scalar_transfer (dtp, BT_COMPLEX, p, kind, size, 1);
}

void
transfer_complex_write (st_parameter_dt *dtp, void *p, int kind)
{
  transfer_complex (dtp, p, kind);
}

void
transfer_array_inner (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
		      gfc_charlen_type charlen)
{
  index_type count[GFC_MAX_DIMENSIONS];
  index_type extent[GFC_MAX_DIMENSIONS];
  index_type stride[GFC_MAX_DIMENSIONS];
  index_type stride0, rank, size, n;
  size_t tsize;
  char *data;
  bt iotype;

  /* Adjust item_count before emitting error message.  */

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;

  iotype = (bt) GFC_DESCRIPTOR_TYPE (desc);
  size = iotype == BT_CHARACTER ? charlen : GFC_DESCRIPTOR_SIZE (desc);

  rank = GFC_DESCRIPTOR_RANK (desc);

  for (n = 0; n < rank; n++)
    {
      count[n] = 0;
      stride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(desc,n);
      extent[n] = GFC_DESCRIPTOR_EXTENT(desc,n);

      /* If the extent of even one dimension is zero, then the entire
	 array section contains zero elements, so we return after writing
	 a zero array record.  */
      if (extent[n] <= 0)
	{
	  data = NULL;
	  tsize = 0;
	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
	  return;
	}
    }

  stride0 = stride[0];

  /* If the innermost dimension has a stride of 1, we can do the transfer
     in contiguous chunks.  */
  if (stride0 == size)
    tsize = extent[0];
  else
    tsize = 1;

  data = GFC_DESCRIPTOR_DATA (desc);

  /* When reading, we need to check endfile conditions so we do not miss
     an END=label.  Make this separate so we do not have an extra test
     in a tight loop when it is not needed.  */

  if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
    {
      while (data)
	{
	  if (unlikely (dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
	    return;

	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
	  data += stride0 * tsize;
	  count[0] += tsize;
	  n = 0;
	  while (count[n] == extent[n])
	    {
	      count[n] = 0;
	      data -= stride[n] * extent[n];
	      n++;
	      if (n == rank)
		{
		  data = NULL;
		  break;
		}
	      else
		{
		  count[n]++;
		  data += stride[n];
		}
	    }
	}
    }
  else
    {
      while (data)
	{
	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
	  data += stride0 * tsize;
	  count[0] += tsize;
	  n = 0;
	  while (count[n] == extent[n])
	    {
	      count[n] = 0;
	      data -= stride[n] * extent[n];
	      n++;
	      if (n == rank)
		{
		  data = NULL;
		  break;
		}
	      else
		{
		  count[n]++;
		  data += stride[n];
		}
	    }
	}
    }
}

void
transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
	        gfc_charlen_type charlen)
{
  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;

  if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
    {
      if (dtp->u.p.async)
	{
	  transfer_args args;
	  size_t sz = sizeof (gfc_array_char)
			+ sizeof (descriptor_dimension)
       			* GFC_DESCRIPTOR_RANK (desc);
	  args.array.desc = xmalloc (sz);
	  NOTE ("desc = %p", (void *) args.array.desc);
	  memcpy (args.array.desc, desc, sz);
	  args.array.kind = kind;
	  args.array.charlen = charlen;
	  enqueue_transfer (dtp->u.p.current_unit->au, &args,
			    AIO_TRANSFER_ARRAY);
	  return;
	}
    }
  /* Come here if there was no asynchronous I/O to be scheduled.  */
  transfer_array_inner (dtp, desc, kind, charlen);
}


void
transfer_array_write (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
		      gfc_charlen_type charlen)
{
  transfer_array (dtp, desc, kind, charlen);
}


/* User defined input/output iomsg. */

#define IOMSG_LEN 256

void
transfer_derived (st_parameter_dt *parent, void *dtio_source, void *dtio_proc)
{
  if (parent->u.p.current_unit)
    {
      if (parent->u.p.current_unit->flags.form == FORM_UNFORMATTED)
	parent->u.p.ufdtio_ptr = (unformatted_dtio) dtio_proc;
      else
	parent->u.p.fdtio_ptr = (formatted_dtio) dtio_proc;
    }
  wrap_scalar_transfer (parent, BT_CLASS, dtio_source, 0, 0, 1);
}


/* Preposition a sequential unformatted file while reading.  */

static void
us_read (st_parameter_dt *dtp, int continued)
{
  ssize_t n, nr;
  GFC_INTEGER_4 i4;
  GFC_INTEGER_8 i8;
  gfc_offset i;

  if (compile_options.record_marker == 0)
    n = sizeof (GFC_INTEGER_4);
  else
    n = compile_options.record_marker;

  nr = sread (dtp->u.p.current_unit->s, &i, n);
  if (unlikely (nr < 0))
    {
      generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
      return;
    }
  else if (nr == 0)
    {
      hit_eof (dtp);
      return;  /* end of file */
    }
  else if (unlikely (n != nr))
    {
      generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
      return;
    }

  int convert = dtp->u.p.current_unit->flags.convert;
#ifdef HAVE_GFC_REAL_17
  convert &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
#endif
  /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here.  */
  if (likely (convert == GFC_CONVERT_NATIVE))
    {
      switch (nr)
	{
	case sizeof(GFC_INTEGER_4):
	  memcpy (&i4, &i, sizeof (i4));
	  i = i4;
	  break;

	case sizeof(GFC_INTEGER_8):
	  memcpy (&i8, &i, sizeof (i8));
	  i = i8;
	  break;

	default:
	  runtime_error ("Illegal value for record marker");
	  break;
	}
    }
  else
    {
      uint32_t u32;
      uint64_t u64;
      switch (nr)
	{
	case sizeof(GFC_INTEGER_4):
	  memcpy (&u32, &i, sizeof (u32));
	  u32 = __builtin_bswap32 (u32);
	  memcpy (&i4, &u32, sizeof (i4));
	  i = i4;
	  break;

	case sizeof(GFC_INTEGER_8):
	  memcpy (&u64, &i, sizeof (u64));
	  u64 = __builtin_bswap64 (u64);
	  memcpy (&i8, &u64, sizeof (i8));
	  i = i8;
	  break;

	default:
	  runtime_error ("Illegal value for record marker");
	  break;
	}
    }

  if (i >= 0)
    {
      dtp->u.p.current_unit->bytes_left_subrecord = i;
      dtp->u.p.current_unit->continued = 0;
    }
  else
    {
      dtp->u.p.current_unit->bytes_left_subrecord = -i;
      dtp->u.p.current_unit->continued = 1;
    }

  if (! continued)
    dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
}


/* Preposition a sequential unformatted file while writing.  This
   amount to writing a bogus length that will be filled in later.  */

static void
us_write (st_parameter_dt *dtp, int continued)
{
  ssize_t nbytes;
  gfc_offset dummy;

  dummy = 0;

  if (compile_options.record_marker == 0)
    nbytes = sizeof (GFC_INTEGER_4);
  else
    nbytes = compile_options.record_marker ;

  if (swrite (dtp->u.p.current_unit->s, &dummy, nbytes) != nbytes)
    generate_error (&dtp->common, LIBERROR_OS, NULL);

  /* For sequential unformatted, if RECL= was not specified in the OPEN
     we write until we have more bytes than can fit in the subrecord
     markers, then we write a new subrecord.  */

  dtp->u.p.current_unit->bytes_left_subrecord =
    dtp->u.p.current_unit->recl_subrecord;
  dtp->u.p.current_unit->continued = continued;
}


/* Position to the next record prior to transfer.  We are assumed to
   be before the next record.  We also calculate the bytes in the next
   record.  */

static void
pre_position (st_parameter_dt *dtp)
{
  if (dtp->u.p.current_unit->current_record)
    return;			/* Already positioned.  */

  switch (current_mode (dtp))
    {
    case FORMATTED_STREAM:
    case UNFORMATTED_STREAM:
      /* There are no records with stream I/O.  If the position was specified
	 data_transfer_init has already positioned the file. If no position
	 was specified, we continue from where we last left off.  I.e.
	 there is nothing to do here.  */
      break;

    case UNFORMATTED_SEQUENTIAL:
      if (dtp->u.p.mode == READING)
	us_read (dtp, 0);
      else
	us_write (dtp, 0);

      break;

    case FORMATTED_SEQUENTIAL:
    case FORMATTED_DIRECT:
    case UNFORMATTED_DIRECT:
      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
      break;
    case FORMATTED_UNSPECIFIED:
      gcc_unreachable ();
    }

  dtp->u.p.current_unit->current_record = 1;
}


/* Initialize things for a data transfer.  This code is common for
   both reading and writing.  */

static void
data_transfer_init (st_parameter_dt *dtp, int read_flag)
{
  unit_flags u_flags;  /* Used for creating a unit if needed.  */
  GFC_INTEGER_4 cf = dtp->common.flags;
  namelist_info *ionml;
  async_unit *au;

  NOTE ("data_transfer_init");

  ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL;

  memset (&dtp->u.p, 0, sizeof (dtp->u.p));

  dtp->u.p.ionml = ionml;
  dtp->u.p.mode = read_flag ? READING : WRITING;
  dtp->u.p.namelist_mode = 0;
  dtp->u.p.cc.len = 0;

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    return;

  dtp->u.p.current_unit = get_unit (dtp, 1);

  if (dtp->u.p.current_unit == NULL)
    {
      /* This means we tried to access an external unit < 0 without
	 having opened it first with NEWUNIT=.  */
      generate_error (&dtp->common, LIBERROR_BAD_OPTION,
		      "Unit number is negative and unit was not already "
		      "opened with OPEN(NEWUNIT=...)");
      return;
    }
  else if (dtp->u.p.current_unit->s == NULL)
    {  /* Open the unit with some default flags.  */
      st_parameter_open opp;
      unit_convert conv;
      NOTE ("Open the unit with some default flags.");
      memset (&u_flags, '\0', sizeof (u_flags));
      u_flags.access = ACCESS_SEQUENTIAL;
      u_flags.action = ACTION_READWRITE;

      /* Is it unformatted?  */
      if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
		  | IOPARM_DT_IONML_SET)))
	u_flags.form = FORM_UNFORMATTED;
      else
	u_flags.form = FORM_UNSPECIFIED;

      u_flags.delim = DELIM_UNSPECIFIED;
      u_flags.blank = BLANK_UNSPECIFIED;
      u_flags.pad = PAD_UNSPECIFIED;
      u_flags.decimal = DECIMAL_UNSPECIFIED;
      u_flags.encoding = ENCODING_UNSPECIFIED;
      u_flags.async = ASYNC_UNSPECIFIED;
      u_flags.round = ROUND_UNSPECIFIED;
      u_flags.sign = SIGN_UNSPECIFIED;
      u_flags.share = SHARE_UNSPECIFIED;
      u_flags.cc = CC_UNSPECIFIED;
      u_flags.readonly = 0;

      u_flags.status = STATUS_UNKNOWN;

      conv = get_unformatted_convert (dtp->common.unit);

      if (conv == GFC_CONVERT_NONE)
	conv = compile_options.convert;

      u_flags.convert = 0;

#ifdef HAVE_GFC_REAL_17
      u_flags.convert = conv & (GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
      conv &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
#endif

      switch (conv)
	{
	case GFC_CONVERT_NATIVE:
	case GFC_CONVERT_SWAP:
	  break;

	case GFC_CONVERT_BIG:
	  conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
	  break;

	case GFC_CONVERT_LITTLE:
	  conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
	  break;

	default:
	  internal_error (&opp.common, "Illegal value for CONVERT");
	  break;
	}

      u_flags.convert |= conv;

      opp.common = dtp->common;
      opp.common.flags &= IOPARM_COMMON_MASK;
      dtp->u.p.current_unit = new_unit (&opp, dtp->u.p.current_unit, &u_flags);
      dtp->common.flags &= ~IOPARM_COMMON_MASK;
      dtp->common.flags |= (opp.common.flags & IOPARM_COMMON_MASK);
      if (dtp->u.p.current_unit == NULL)
	return;
    }

  if (dtp->u.p.current_unit->child_dtio == 0)
    {
      if ((cf & IOPARM_DT_HAS_SIZE) != 0)
	{
	  dtp->u.p.current_unit->has_size = true;
	  /* Initialize the count.  */
	  dtp->u.p.current_unit->size_used = 0;
	}
      else
	dtp->u.p.current_unit->has_size = false;
    }
  else if (dtp->u.p.current_unit->internal_unit_kind > 0)
    dtp->u.p.unit_is_internal = 1;

  if ((cf & IOPARM_DT_HAS_ASYNCHRONOUS) != 0)
    {
      int f;
      f = find_option (&dtp->common, dtp->asynchronous, dtp->asynchronous_len,
		       async_opt, "Bad ASYNCHRONOUS in data transfer "
		       "statement");
      if (f == ASYNC_YES && dtp->u.p.current_unit->flags.async != ASYNC_YES)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "ASYNCHRONOUS transfer without "
			  "ASYHCRONOUS='YES' in OPEN");
	  return;
	}
      dtp->u.p.async = f == ASYNC_YES;
    }

  au = dtp->u.p.current_unit->au;
  if (au)
    {
      if (dtp->u.p.async)
	{
	  /* If this is an asynchronous I/O statement, collect errors and
	     return if there are any.  */
	  if (collect_async_errors (&dtp->common, au))
	    return;
	}
      else
	{
	  /* Synchronous statement: Perform a wait operation for any pending
	     asynchronous I/O.  This needs to be done before all other error
	     checks.  See F2008, 9.6.4.1.  */
	  if (async_wait (&(dtp->common), au))
	    return;
	}
    }

  /* Check the action.  */

  if (read_flag && dtp->u.p.current_unit->flags.action == ACTION_WRITE)
    {
      generate_error (&dtp->common, LIBERROR_BAD_ACTION,
		      "Cannot read from file opened for WRITE");
      return;
    }

  if (!read_flag && dtp->u.p.current_unit->flags.action == ACTION_READ)
    {
      generate_error (&dtp->common, LIBERROR_BAD_ACTION,
		      "Cannot write to file opened for READ");
      return;
    }

  dtp->u.p.first_item = 1;

  /* Check the format.  */

  if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
    parse_format (dtp);

  if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
      && (cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
	 != 0)
    {
      generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
		      "Format present for UNFORMATTED data transfer");
      return;
    }

  if ((cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0 && dtp->u.p.ionml != NULL)
     {
	if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
	  {
	    generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			"A format cannot be specified with a namelist");
	    return;
	  }
     }
  else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
	   !(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT)))
    {
      generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
		      "Missing format for FORMATTED data transfer");
      return;
    }

  if (is_internal_unit (dtp)
      && dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
    {
      generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
		      "Internal file cannot be accessed by UNFORMATTED "
		      "data transfer");
      return;
    }

  /* Check the record or position number.  */

  if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT
      && (cf & IOPARM_DT_HAS_REC) == 0)
    {
      generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
		      "Direct access data transfer requires record number");
      return;
    }

  if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
    {
      if ((cf & IOPARM_DT_HAS_REC) != 0)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			"Record number not allowed for sequential access "
			"data transfer");
	  return;
	}

      if (compile_options.warn_std &&
	  dtp->u.p.current_unit->endfile == AFTER_ENDFILE)
      	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			"Sequential READ or WRITE not allowed after "
			"EOF marker, possibly use REWIND or BACKSPACE");
	  return;
	}
    }

  /* Process the ADVANCE option.  */

  dtp->u.p.advance_status
    = !(cf & IOPARM_DT_HAS_ADVANCE) ? ADVANCE_UNSPECIFIED :
      find_option (&dtp->common, dtp->advance, dtp->advance_len, advance_opt,
		   "Bad ADVANCE parameter in data transfer statement");

  if (dtp->u.p.advance_status != ADVANCE_UNSPECIFIED)
    {
      if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "ADVANCE specification conflicts with sequential "
			  "access");
	  return;
	}

      if (is_internal_unit (dtp))
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "ADVANCE specification conflicts with internal file");
	  return;
	}

      if ((cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
	  != IOPARM_DT_HAS_FORMAT)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "ADVANCE specification requires an explicit format");
	  return;
	}
    }

  /* Child IO is non-advancing and any ADVANCE= specifier is ignored.
     F2008 9.6.2.4  */
  if (dtp->u.p.current_unit->child_dtio  > 0)
    dtp->u.p.advance_status = ADVANCE_NO;

  if (read_flag)
    {
      dtp->u.p.current_unit->previous_nonadvancing_write = 0;

      if ((cf & IOPARM_EOR) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
	{
	  generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
			  "EOR specification requires an ADVANCE specification "
			  "of NO");
	  return;
	}

      if ((cf & IOPARM_DT_HAS_SIZE) != 0
	  && dtp->u.p.advance_status != ADVANCE_NO)
	{
	  generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
			  "SIZE specification requires an ADVANCE "
			  "specification of NO");
	  return;
	}
    }
  else
    {				/* Write constraints.  */
      if ((cf & IOPARM_END) != 0)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "END specification cannot appear in a write "
			  "statement");
	  return;
	}

      if ((cf & IOPARM_EOR) != 0)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "EOR specification cannot appear in a write "
			  "statement");
	  return;
	}

      if ((cf & IOPARM_DT_HAS_SIZE) != 0)
	{
	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			  "SIZE specification cannot appear in a write "
			  "statement");
	  return;
	}
    }

  if (dtp->u.p.advance_status == ADVANCE_UNSPECIFIED)
    dtp->u.p.advance_status = ADVANCE_YES;

  /* Check the decimal mode.  */
  dtp->u.p.current_unit->decimal_status
	= !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
	  find_option (&dtp->common, dtp->decimal, dtp->decimal_len,
			decimal_opt, "Bad DECIMAL parameter in data transfer "
			"statement");

  if (dtp->u.p.current_unit->decimal_status == DECIMAL_UNSPECIFIED)
	dtp->u.p.current_unit->decimal_status = dtp->u.p.current_unit->flags.decimal;

  /* Check the round mode.  */
  dtp->u.p.current_unit->round_status
	= !(cf & IOPARM_DT_HAS_ROUND) ? ROUND_UNSPECIFIED :
	  find_option (&dtp->common, dtp->round, dtp->round_len,
			round_opt, "Bad ROUND parameter in data transfer "
			"statement");

  if (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED)
	dtp->u.p.current_unit->round_status = dtp->u.p.current_unit->flags.round;

  /* Check the sign mode. */
  dtp->u.p.sign_status
	= !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
	  find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt,
			"Bad SIGN parameter in data transfer statement");

  if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
	dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;

  /* Check the blank mode.  */
  dtp->u.p.blank_status
	= !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
	  find_option (&dtp->common, dtp->blank, dtp->blank_len,
			blank_opt,
			"Bad BLANK parameter in data transfer statement");

  if (dtp->u.p.blank_status == BLANK_UNSPECIFIED)
	dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;

  /* Check the delim mode.  */
  dtp->u.p.current_unit->delim_status
	= !(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)
    {
      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;

  /* Set up the subroutine that will handle the transfers.  */

  if (read_flag)
    {
      if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
	dtp->u.p.transfer = unformatted_read;
      else
	{
	  if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
	    dtp->u.p.transfer = list_formatted_read;
	  else
	    dtp->u.p.transfer = formatted_transfer;
	}
    }
  else
    {
      if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
	dtp->u.p.transfer = unformatted_write;
      else
	{
	  if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
	    dtp->u.p.transfer = list_formatted_write;
	  else
	    dtp->u.p.transfer = formatted_transfer;
	}
    }

  if (au && dtp->u.p.async)
    {
      NOTE ("enqueue_data_transfer");
      enqueue_data_transfer_init (au, dtp, read_flag);
    }
  else
    {
      NOTE ("invoking data_transfer_init_worker");
      data_transfer_init_worker (dtp, read_flag);
    }
}

void
data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
{
  GFC_INTEGER_4 cf = dtp->common.flags;

  NOTE ("starting worker...");

  if (read_flag && dtp->u.p.current_unit->flags.form != FORM_UNFORMATTED
      && ((cf & IOPARM_DT_LIST_FORMAT) != 0)
      && dtp->u.p.current_unit->child_dtio  == 0)
    dtp->u.p.current_unit->last_char = EOF - 1;

  /* Check to see if we might be reading what we wrote before  */

  if (dtp->u.p.mode != dtp->u.p.current_unit->mode
      && !is_internal_unit (dtp))
    {
      int pos = fbuf_reset (dtp->u.p.current_unit);
      if (pos != 0)
        sseek (dtp->u.p.current_unit->s, pos, SEEK_CUR);
      sflush(dtp->u.p.current_unit->s);
    }

  /* Check the POS= specifier: that it is in range and that it is used with a
     unit that has been connected for STREAM access. F2003 9.5.1.10.  */

  if (((cf & IOPARM_DT_HAS_POS) != 0))
    {
      if (is_stream_io (dtp))
        {

          if (dtp->pos <= 0)
            {
              generate_error (&dtp->common, LIBERROR_BAD_OPTION,
                              "POS=specifier must be positive");
              return;
            }

          if (dtp->pos >= dtp->u.p.current_unit->maxrec)
            {
              generate_error (&dtp->common, LIBERROR_BAD_OPTION,
                              "POS=specifier too large");
              return;
            }

          dtp->rec = dtp->pos;

          if (dtp->u.p.mode == READING)
            {
              /* Reset the endfile flag; if we hit EOF during reading
                 we'll set the flag and generate an error at that point
                 rather than worrying about it here.  */
              dtp->u.p.current_unit->endfile = NO_ENDFILE;
            }

          if (dtp->pos != dtp->u.p.current_unit->strm_pos)
            {
	      fbuf_reset (dtp->u.p.current_unit);
	      if (sseek (dtp->u.p.current_unit->s, dtp->pos - 1,
			 SEEK_SET) < 0)
                {
                  generate_error (&dtp->common, LIBERROR_OS, NULL);
                  return;
                }
              dtp->u.p.current_unit->strm_pos = dtp->pos;
            }
        }
      else
        {
          generate_error (&dtp->common, LIBERROR_BAD_OPTION,
                          "POS=specifier not allowed, "
                          "Try OPEN with ACCESS='stream'");
          return;
        }
    }


  /* Sanity checks on the record number.  */
  if ((cf & IOPARM_DT_HAS_REC) != 0)
    {
      if (dtp->rec <= 0)
	{
	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
			  "Record number must be positive");
	  return;
	}

      if (dtp->rec >= dtp->u.p.current_unit->maxrec)
	{
	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
			  "Record number too large");
	  return;
	}

      /* Make sure format buffer is reset.  */
      if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
        fbuf_reset (dtp->u.p.current_unit);


      /* Check whether the record exists to be read.  Only
	 a partial record needs to exist.  */

      if (dtp->u.p.mode == READING && (dtp->rec - 1)
	  * dtp->u.p.current_unit->recl >= ssize (dtp->u.p.current_unit->s))
	{
	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
			  "Non-existing record number");
	  return;
	}

      /* Position the file.  */
      if (sseek (dtp->u.p.current_unit->s, (gfc_offset) (dtp->rec - 1)
		 * dtp->u.p.current_unit->recl, SEEK_SET) < 0)
	{
	  generate_error (&dtp->common, LIBERROR_OS, NULL);
	  return;
	}

      if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
       {
         generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
                     "Record number not allowed for stream access "
                     "data transfer");
         return;
       }
    }

  /* Bugware for badly written mixed C-Fortran I/O.  */
  if (!is_internal_unit (dtp))
    flush_if_preconnected(dtp->u.p.current_unit->s);

  dtp->u.p.current_unit->mode = dtp->u.p.mode;

  /* Set the maximum position reached from the previous I/O operation.  This
     could be greater than zero from a previous non-advancing write.  */
  dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;

  pre_position (dtp);

  /* Make sure that we don't do a read after a nonadvancing write.  */

  if (read_flag)
    {
      if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
	{
	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
			  "Cannot READ after a nonadvancing WRITE");
	  return;
	}
    }
  else
    {
      if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
	dtp->u.p.current_unit->read_bad = 1;
    }

  if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
    {
#ifdef HAVE_POSIX_2008_LOCALE
      dtp->u.p.old_locale = uselocale (c_locale);
#else
      __gthread_mutex_lock (&old_locale_lock);
      if (!old_locale_ctr++)
	{
	  old_locale = setlocale (LC_NUMERIC, NULL);
	  setlocale (LC_NUMERIC, "C");
	}
      __gthread_mutex_unlock (&old_locale_lock);
#endif
      /* Start the data transfer if we are doing a formatted transfer.  */
      if ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0
	&& dtp->u.p.ionml == NULL)
	formatted_transfer (dtp, 0, NULL, 0, 0, 1);
    }
}


/* Initialize an array_loop_spec given the array descriptor.  The function
   returns the index of the last element of the array, and also returns
   starting record, where the first I/O goes to (necessary in case of
   negative strides).  */

gfc_offset
init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
		gfc_offset *start_record)
{
  int rank = GFC_DESCRIPTOR_RANK(desc);
  int i;
  gfc_offset index;
  int empty;

  empty = 0;
  index = 1;
  *start_record = 0;

  for (i=0; i<rank; i++)
    {
      ls[i].idx = GFC_DESCRIPTOR_LBOUND(desc,i);
      ls[i].start = GFC_DESCRIPTOR_LBOUND(desc,i);
      ls[i].end = GFC_DESCRIPTOR_UBOUND(desc,i);
      ls[i].step = GFC_DESCRIPTOR_STRIDE(desc,i);
      empty = empty || (GFC_DESCRIPTOR_UBOUND(desc,i)
			< GFC_DESCRIPTOR_LBOUND(desc,i));

      if (GFC_DESCRIPTOR_STRIDE(desc,i) > 0)
	{
	  index += (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
	    * GFC_DESCRIPTOR_STRIDE(desc,i);
	}
      else
	{
	  index -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
	    * GFC_DESCRIPTOR_STRIDE(desc,i);
	  *start_record -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
	    * GFC_DESCRIPTOR_STRIDE(desc,i);
	}
    }

  if (empty)
    return 0;
  else
    return index;
}

/* Determine the index to the next record in an internal unit array by
   by incrementing through the array_loop_spec.  */

gfc_offset
next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
{
  int i, carry;
  gfc_offset index;

  carry = 1;
  index = 0;

  for (i = 0; i < dtp->u.p.current_unit->rank; i++)
    {
      if (carry)
        {
          ls[i].idx++;
          if (ls[i].idx > ls[i].end)
            {
              ls[i].idx = ls[i].start;
              carry = 1;
            }
          else
            carry = 0;
        }
      index = index + (ls[i].idx - ls[i].start) * ls[i].step;
    }

  *finished = carry;

  return index;
}



/* Skip to the end of the current record, taking care of an optional
   record marker of size bytes.  If the file is not seekable, we
   read chunks of size MAX_READ until we get to the right
   position.  */

static void
skip_record (st_parameter_dt *dtp, gfc_offset bytes)
{
  ssize_t rlength, readb;
#define MAX_READ 4096
  char p[MAX_READ];

  dtp->u.p.current_unit->bytes_left_subrecord += bytes;
  if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
    return;

  /* Direct access files do not generate END conditions,
     only I/O errors.  */
  if (sseek (dtp->u.p.current_unit->s,
	     dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
    {
      /* Seeking failed, fall back to seeking by reading data.  */
      while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
	{
	  rlength =
	    (MAX_READ < dtp->u.p.current_unit->bytes_left_subrecord) ?
	    MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;

	  readb = sread (dtp->u.p.current_unit->s, p, rlength);
	  if (readb < 0)
	    {
	      generate_error (&dtp->common, LIBERROR_OS, NULL);
	      return;
	    }

	  dtp->u.p.current_unit->bytes_left_subrecord -= readb;
	}
      return;
    }
  dtp->u.p.current_unit->bytes_left_subrecord = 0;
}


/* Advance to the next record reading unformatted files, taking
   care of subrecords.  If complete_record is nonzero, we loop
   until all subrecords are cleared.  */

static void
next_record_r_unf (st_parameter_dt *dtp, int complete_record)
{
  size_t bytes;

  bytes =  compile_options.record_marker == 0 ?
    sizeof (GFC_INTEGER_4) : compile_options.record_marker;

  while(1)
    {

      /* Skip over tail */

      skip_record (dtp, bytes);

      if ( ! (complete_record && dtp->u.p.current_unit->continued))
	return;

      us_read (dtp, 1);
    }
}


static gfc_offset
min_off (gfc_offset a, gfc_offset b)
{
  return (a < b ? a : b);
}


/* Space to the next record for read mode.  */

static void
next_record_r (st_parameter_dt *dtp, int done)
{
  gfc_offset record;
  char p;
  int cc;

  switch (current_mode (dtp))
    {
    /* No records in unformatted STREAM I/O.  */
    case UNFORMATTED_STREAM:
      return;

    case UNFORMATTED_SEQUENTIAL:
      next_record_r_unf (dtp, 1);
      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
      break;

    case FORMATTED_DIRECT:
    case UNFORMATTED_DIRECT:
      skip_record (dtp, dtp->u.p.current_unit->bytes_left);
      break;

    case FORMATTED_STREAM:
    case FORMATTED_SEQUENTIAL:
      /* read_sf has already terminated input because of an '\n', or
         we have hit EOF.  */
      if (dtp->u.p.sf_seen_eor)
	{
	  dtp->u.p.sf_seen_eor = 0;
	  break;
	}

      if (is_internal_unit (dtp))
	{
	  if (is_array_io (dtp))
	    {
	      int finished;

	      record = next_array_record (dtp, dtp->u.p.current_unit->ls,
					  &finished);
	      if (!done && finished)
		hit_eof (dtp);

	      /* Now seek to this record.  */
	      record = record * dtp->u.p.current_unit->recl;
	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
		{
		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
		  break;
		}
	      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
	    }
	  else
	    {
	      gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
	      bytes_left = min_off (bytes_left,
		      ssize (dtp->u.p.current_unit->s)
		      - stell (dtp->u.p.current_unit->s));
	      if (sseek (dtp->u.p.current_unit->s,
			 bytes_left, SEEK_CUR) < 0)
	        {
		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
		  break;
		}
	      dtp->u.p.current_unit->bytes_left
		= dtp->u.p.current_unit->recl;
	    }
	  break;
	}
      else if (dtp->u.p.current_unit->flags.cc != CC_NONE)
	{
	  do
	    {
              errno = 0;
              cc = fbuf_getc (dtp->u.p.current_unit);
	      if (cc == EOF)
		{
                  if (errno != 0)
                    generate_error (&dtp->common, LIBERROR_OS, NULL);
		  else
		    {
		      if (is_stream_io (dtp)
			  || dtp->u.p.current_unit->pad_status == PAD_NO
			  || dtp->u.p.current_unit->bytes_left
			     == dtp->u.p.current_unit->recl)
			hit_eof (dtp);
		    }
		  break;
                }

	      if (is_stream_io (dtp))
		dtp->u.p.current_unit->strm_pos++;

              p = (char) cc;
	    }
	  while (p != '\n');
	}
      break;
    case FORMATTED_UNSPECIFIED:
      gcc_unreachable ();
    }
}


/* Small utility function to write a record marker, taking care of
   byte swapping and of choosing the correct size.  */

static int
write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
{
  size_t len;
  GFC_INTEGER_4 buf4;
  GFC_INTEGER_8 buf8;

  if (compile_options.record_marker == 0)
    len = sizeof (GFC_INTEGER_4);
  else
    len = compile_options.record_marker;

  int convert = dtp->u.p.current_unit->flags.convert;
#ifdef HAVE_GFC_REAL_17
  convert &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
#endif
  /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here.  */
  if (likely (convert == GFC_CONVERT_NATIVE))
    {
      switch (len)
	{
	case sizeof (GFC_INTEGER_4):
	  buf4 = buf;
	  return swrite (dtp->u.p.current_unit->s, &buf4, len);
	  break;

	case sizeof (GFC_INTEGER_8):
	  buf8 = buf;
	  return swrite (dtp->u.p.current_unit->s, &buf8, len);
	  break;

	default:
	  runtime_error ("Illegal value for record marker");
	  break;
	}
    }
  else
    {
      uint32_t u32;
      uint64_t u64;
      switch (len)
	{
	case sizeof (GFC_INTEGER_4):
	  buf4 = buf;
	  memcpy (&u32, &buf4, sizeof (u32));
	  u32 = __builtin_bswap32 (u32);
	  return swrite (dtp->u.p.current_unit->s, &u32, len);
	  break;

	case sizeof (GFC_INTEGER_8):
	  buf8 = buf;
	  memcpy (&u64, &buf8, sizeof (u64));
	  u64 = __builtin_bswap64 (u64);
	  return swrite (dtp->u.p.current_unit->s, &u64, len);
	  break;

	default:
	  runtime_error ("Illegal value for record marker");
	  break;
	}
    }

}

/* Position to the next (sub)record in write mode for
   unformatted sequential files.  */

static void
next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
{
  gfc_offset m, m_write, record_marker;

  /* Bytes written.  */
  m = dtp->u.p.current_unit->recl_subrecord
    - dtp->u.p.current_unit->bytes_left_subrecord;

  if (compile_options.record_marker == 0)
    record_marker = sizeof (GFC_INTEGER_4);
  else
    record_marker = compile_options.record_marker;

  /* Seek to the head and overwrite the bogus length with the real
     length.  */

  if (unlikely (sseek (dtp->u.p.current_unit->s, - m - record_marker,
		       SEEK_CUR) < 0))
    goto io_error;

  if (next_subrecord)
    m_write = -m;
  else
    m_write = m;

  if (unlikely (write_us_marker (dtp, m_write) < 0))
    goto io_error;

  /* Seek past the end of the current record.  */

  if (unlikely (sseek (dtp->u.p.current_unit->s, m, SEEK_CUR) < 0))
    goto io_error;

  /* Write the length tail.  If we finish a record containing
     subrecords, we write out the negative length.  */

  if (dtp->u.p.current_unit->continued)
    m_write = -m;
  else
    m_write = m;

  if (unlikely (write_us_marker (dtp, m_write) < 0))
    goto io_error;

  return;

 io_error:
  generate_error (&dtp->common, LIBERROR_OS, NULL);
  return;

}


/* Utility function like memset() but operating on streams. Return
   value is same as for POSIX write().  */

static gfc_offset
sset (stream *s, int c, gfc_offset nbyte)
{
#define WRITE_CHUNK 256
  char p[WRITE_CHUNK];
  gfc_offset bytes_left;
  ssize_t trans;

  if (nbyte < WRITE_CHUNK)
    memset (p, c, nbyte);
  else
    memset (p, c, WRITE_CHUNK);

  bytes_left = nbyte;
  while (bytes_left > 0)
    {
      trans = (bytes_left < WRITE_CHUNK) ? bytes_left : WRITE_CHUNK;
      trans = swrite (s, p, trans);
      if (trans <= 0)
	return trans;
      bytes_left -= trans;
    }

  return nbyte - bytes_left;
}


/* Finish up a record according to the legacy carriagecontrol type, based
   on the first character in the record.  */

static void
next_record_cc (st_parameter_dt *dtp)
{
  /* Only valid with CARRIAGECONTROL=FORTRAN.  */
  if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
    return;

  fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
  if (dtp->u.p.cc.len > 0)
    {
      char *p = fbuf_alloc (dtp->u.p.current_unit, dtp->u.p.cc.len);
      if (!p)
	generate_error (&dtp->common, LIBERROR_OS, NULL);

      /* Output CR for the first character with default CC setting.  */
      *(p++) = dtp->u.p.cc.u.end;
      if (dtp->u.p.cc.len > 1)
	*p = dtp->u.p.cc.u.end;
    }
}

/* Position to the next record in write mode.  */

static void
next_record_w (st_parameter_dt *dtp, int done)
{
  gfc_offset max_pos_off;

  /* Zero counters for X- and T-editing.  */
  max_pos_off = dtp->u.p.max_pos;
  dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;

  switch (current_mode (dtp))
    {
    /* No records in unformatted STREAM I/O.  */
    case UNFORMATTED_STREAM:
      return;

    case FORMATTED_DIRECT:
      if (dtp->u.p.current_unit->bytes_left == 0)
	break;

      fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
      fbuf_flush (dtp->u.p.current_unit, WRITING);
      if (sset (dtp->u.p.current_unit->s, ' ',
		dtp->u.p.current_unit->bytes_left)
	  != dtp->u.p.current_unit->bytes_left)
	goto io_error;

      break;

    case UNFORMATTED_DIRECT:
      if (dtp->u.p.current_unit->bytes_left > 0)
	{
	  gfc_offset length = dtp->u.p.current_unit->bytes_left;
	  if (sset (dtp->u.p.current_unit->s, 0, length) != length)
	    goto io_error;
	}
      break;

    case UNFORMATTED_SEQUENTIAL:
      next_record_w_unf (dtp, 0);
      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
      break;

    case FORMATTED_STREAM:
    case FORMATTED_SEQUENTIAL:

      if (is_internal_unit (dtp))
	{
	  char *p;
	  /* Internal unit, so must fit in memory.  */
	  size_t length, m;
	  size_t max_pos = max_pos_off;
	  if (is_array_io (dtp))
	    {
	      int finished;

	      length = dtp->u.p.current_unit->bytes_left;

	      /* If the farthest position reached is greater than current
	      position, adjust the position and set length to pad out
	      whats left.  Otherwise just pad whats left.
	      (for character array unit) */
	      m = dtp->u.p.current_unit->recl
			- dtp->u.p.current_unit->bytes_left;
	      if (max_pos > m)
		{
		  length = (max_pos - m);
		  if (sseek (dtp->u.p.current_unit->s,
			     length, SEEK_CUR) < 0)
		    {
		      generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
		      return;
		    }
		  length = ((size_t) dtp->u.p.current_unit->recl - max_pos);
		}

	      p = write_block (dtp, length);
	      if (p == NULL)
		return;

	      if (unlikely (is_char4_unit (dtp)))
	        {
		  gfc_char4_t *p4 = (gfc_char4_t *) p;
		  memset4 (p4, ' ', length);
		}
	      else
		memset (p, ' ', length);

	      /* Now that the current record has been padded out,
		 determine where the next record in the array is.
		 Note that this can return a negative value, so it
		 needs to be assigned to a signed value.  */
	      gfc_offset record = next_array_record
		(dtp, dtp->u.p.current_unit->ls, &finished);
	      if (finished)
		dtp->u.p.current_unit->endfile = AT_ENDFILE;

	      /* Now seek to this record */
	      record = record * dtp->u.p.current_unit->recl;

	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
		{
		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
		  return;
		}

	      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
	    }
	  else
	    {
	      length = 1;

	      /* If this is the last call to next_record move to the farthest
		 position reached and set length to pad out the remainder
		 of the record. (for character scaler unit) */
	      if (done)
		{
		  m = dtp->u.p.current_unit->recl
			- dtp->u.p.current_unit->bytes_left;
		  if (max_pos > m)
		    {
		      length = max_pos - m;
		      if (sseek (dtp->u.p.current_unit->s,
				 length, SEEK_CUR) < 0)
		        {
			  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
			  return;
			}
		      length = (size_t) dtp->u.p.current_unit->recl
			- max_pos;
		    }
		  else
		    length = dtp->u.p.current_unit->bytes_left;
		}
	      if (length > 0)
		{
		  p = write_block (dtp, length);
		  if (p == NULL)
		    return;

		  if (unlikely (is_char4_unit (dtp)))
		    {
		      gfc_char4_t *p4 = (gfc_char4_t *) p;
		      memset4 (p4, (gfc_char4_t) ' ', length);
		    }
		  else
		    memset (p, ' ', length);
		}
	    }
	}
      else if (dtp->u.p.seen_dollar == 1)
	break;
      /* Handle legacy CARRIAGECONTROL line endings.  */
      else if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
	next_record_cc (dtp);
      else
	{
	  /* Skip newlines for CC=CC_NONE.  */
	  const int len = (dtp->u.p.current_unit->flags.cc == CC_NONE)
	    ? 0
#ifdef HAVE_CRLF
	    : 2;
#else
	    : 1;
#endif
	  fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
	  if (dtp->u.p.current_unit->flags.cc != CC_NONE)
	    {
	      char *p = fbuf_alloc (dtp->u.p.current_unit, len);
	      if (!p)
		goto io_error;
#ifdef HAVE_CRLF
	      *(p++) = '\r';
#endif
	      *p = '\n';
	    }
	  if (is_stream_io (dtp))
	    {
	      dtp->u.p.current_unit->strm_pos += len;
	      if (dtp->u.p.current_unit->strm_pos
		  < ssize (dtp->u.p.current_unit->s))
		unit_truncate (dtp->u.p.current_unit,
                               dtp->u.p.current_unit->strm_pos - 1,
                               &dtp->common);
	    }
	}

      break;
    case FORMATTED_UNSPECIFIED:
      gcc_unreachable ();

    io_error:
      generate_error (&dtp->common, LIBERROR_OS, NULL);
      break;
    }
}

/* Position to the next record, which means moving to the end of the
   current record.  This can happen under several different
   conditions.  If the done flag is not set, we get ready to process
   the next record.  */

void
next_record (st_parameter_dt *dtp, int done)
{
  gfc_offset fp; /* File position.  */

  dtp->u.p.current_unit->read_bad = 0;

  if (dtp->u.p.mode == READING)
    next_record_r (dtp, done);
  else
    next_record_w (dtp, done);

  fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);

  if (!is_stream_io (dtp))
    {
      /* Since we have changed the position, set it to unspecified so
	 that INQUIRE(POSITION=) knows it needs to look into it.  */
      if (done)
	dtp->u.p.current_unit->flags.position = POSITION_UNSPECIFIED;

      dtp->u.p.current_unit->current_record = 0;
      if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
	{
	  fp = stell (dtp->u.p.current_unit->s);
	  /* Calculate next record, rounding up partial records.  */
	  dtp->u.p.current_unit->last_record =
	    (fp + dtp->u.p.current_unit->recl) /
	      dtp->u.p.current_unit->recl - 1;
	}
      else
	dtp->u.p.current_unit->last_record++;
    }

  if (!done)
    pre_position (dtp);

  smarkeor (dtp->u.p.current_unit->s);
}


/* Finalize the current data transfer.  For a nonadvancing transfer,
   this means advancing to the next record.  For internal units close the
   stream associated with the unit.  */

static void
finalize_transfer (st_parameter_dt *dtp)
{
  GFC_INTEGER_4 cf = dtp->common.flags;

  if ((dtp->u.p.ionml != NULL)
      && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
    {
       if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
	 {
	   generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
			   "Namelist formatting for unit connected "
			   "with FORM='UNFORMATTED'");
	   return;
	 }

       dtp->u.p.namelist_mode = 1;
       if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
	 namelist_read (dtp);
       else
	 namelist_write (dtp);
    }

  if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
    *dtp->size = dtp->u.p.current_unit->size_used;

  if (dtp->u.p.eor_condition)
    {
      generate_error (&dtp->common, LIBERROR_EOR, NULL);
      goto done;
    }

  if (dtp->u.p.current_unit && (dtp->u.p.current_unit->child_dtio  > 0))
    {
      if (cf & IOPARM_DT_HAS_FORMAT)
        {
	  free (dtp->u.p.fmt);
	  free (dtp->format);
	}
      return;
    }

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    {
      if (dtp->u.p.current_unit && current_mode (dtp) == UNFORMATTED_SEQUENTIAL)
	dtp->u.p.current_unit->current_record = 0;
      goto done;
    }

  dtp->u.p.transfer = NULL;
  if (dtp->u.p.current_unit == NULL)
    goto done;

  if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
    {
      finish_list_read (dtp);
      goto done;
    }

  if (dtp->u.p.mode == WRITING)
    dtp->u.p.current_unit->previous_nonadvancing_write
      = dtp->u.p.advance_status == ADVANCE_NO;

  if (is_stream_io (dtp))
    {
      if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
	  && dtp->u.p.advance_status != ADVANCE_NO)
	next_record (dtp, 1);

      goto done;
    }

  dtp->u.p.current_unit->current_record = 0;

  if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
    {
      fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
      dtp->u.p.seen_dollar = 0;
      goto done;
    }

  /* For non-advancing I/O, save the current maximum position for use in the
     next I/O operation if needed.  */
  if (dtp->u.p.advance_status == ADVANCE_NO)
    {
      if (dtp->u.p.skips > 0)
	{
	  int tmp;
	  write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
	  tmp = (int)(dtp->u.p.current_unit->recl
		      - dtp->u.p.current_unit->bytes_left);
	  dtp->u.p.max_pos =
	    dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
	  dtp->u.p.skips = 0;
	}
      int bytes_written = (int) (dtp->u.p.current_unit->recl
	- dtp->u.p.current_unit->bytes_left);
      dtp->u.p.current_unit->saved_pos =
	dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
      fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
      goto done;
    }
  else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
           && dtp->u.p.mode == WRITING && !is_internal_unit (dtp))
      fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);

  dtp->u.p.current_unit->saved_pos = 0;
  dtp->u.p.current_unit->last_char = EOF - 1;
  next_record (dtp, 1);

 done:

  if (dtp->u.p.unit_is_internal)
    {
      /* The unit structure may be reused later so clear the
	 internal unit kind.  */
      dtp->u.p.current_unit->internal_unit_kind = 0;

      fbuf_destroy (dtp->u.p.current_unit);
      if (dtp->u.p.current_unit
	  && (dtp->u.p.current_unit->child_dtio  == 0)
	  && dtp->u.p.current_unit->s)
	{
	  sclose (dtp->u.p.current_unit->s);
	  dtp->u.p.current_unit->s = NULL;
	}
    }

#ifdef HAVE_POSIX_2008_LOCALE
  if (dtp->u.p.old_locale != (locale_t) 0)
    {
      uselocale (dtp->u.p.old_locale);
      dtp->u.p.old_locale = (locale_t) 0;
    }
#else
  __gthread_mutex_lock (&old_locale_lock);
  if (!--old_locale_ctr)
    {
      setlocale (LC_NUMERIC, old_locale);
      old_locale = NULL;
    }
  __gthread_mutex_unlock (&old_locale_lock);
#endif
}

/* Transfer function for IOLENGTH. It doesn't actually do any
   data transfer, it just updates the length counter.  */

static void
iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
		   void *dest __attribute__ ((unused)),
		   int kind __attribute__((unused)),
		   size_t size, size_t nelems)
{
  if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
    *dtp->iolength += (GFC_IO_INT) (size * nelems);
}


/* Initialize the IOLENGTH data transfer. This function is in essence
   a very much simplified version of data_transfer_init(), because it
   doesn't have to deal with units at all.  */

static void
iolength_transfer_init (st_parameter_dt *dtp)
{
  if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
    *dtp->iolength = 0;

  memset (&dtp->u.p, 0, sizeof (dtp->u.p));

  /* Set up the subroutine that will handle the transfers.  */

  dtp->u.p.transfer = iolength_transfer;
}


/* Library entry point for the IOLENGTH form of the INQUIRE
   statement. The IOLENGTH form requires no I/O to be performed, but
   it must still be a runtime library call so that we can determine
   the iolength for dynamic arrays and such.  */

extern void st_iolength (st_parameter_dt *);
export_proto(st_iolength);

void
st_iolength (st_parameter_dt *dtp)
{
  library_start (&dtp->common);
  iolength_transfer_init (dtp);
}

extern void st_iolength_done (st_parameter_dt *);
export_proto(st_iolength_done);

void
st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
{
  free_ionml (dtp);
  library_end ();
}


/* The READ statement.  */

extern void st_read (st_parameter_dt *);
export_proto(st_read);

void
st_read (st_parameter_dt *dtp)
{
  library_start (&dtp->common);

  data_transfer_init (dtp, 1);
}

extern void st_read_done (st_parameter_dt *);
export_proto(st_read_done);

void
st_read_done_worker (st_parameter_dt *dtp, bool unlock)
{
  bool free_newunit = false;
  finalize_transfer (dtp);

  free_ionml (dtp);

  /* If this is a parent READ statement we do not need to retain the
     internal unit structure for child use.  */
  if (dtp->u.p.current_unit != NULL
      && dtp->u.p.current_unit->child_dtio == 0)
    {
      if (dtp->u.p.unit_is_internal)
	{
	  if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
	    {
	      free (dtp->u.p.current_unit->filename);
	      dtp->u.p.current_unit->filename = NULL;
	      free (dtp->u.p.current_unit->ls);
	      dtp->u.p.current_unit->ls = NULL;
	    }
	  free_newunit = true;
	}
      if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
	{
	  free_format_data (dtp->u.p.fmt);
	  free_format (dtp);
	}
    }
   if (unlock)
     unlock_unit (dtp->u.p.current_unit);
   if (free_newunit)
     {
       /* Avoid inverse lock issues by placing after unlock_unit.  */
       WRLOCK (&unit_rwlock);
       newunit_free (dtp->common.unit);
       RWUNLOCK (&unit_rwlock);
     }
}

void
st_read_done (st_parameter_dt *dtp)
{
  if (dtp->u.p.current_unit)
    {
      if (dtp->u.p.current_unit->au)
	{
	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);
	  else
	    {
	      if (dtp->u.p.async)
		enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
	    }
	  unlock_unit (dtp->u.p.current_unit);
	}
      else
	st_read_done_worker (dtp, true);  /* Calls unlock_unit.  */
    }

  library_end ();
}

extern void st_write (st_parameter_dt *);
export_proto (st_write);

void
st_write (st_parameter_dt *dtp)
{
  library_start (&dtp->common);
  data_transfer_init (dtp, 0);
}


void
st_write_done_worker (st_parameter_dt *dtp, bool unlock)
{
  bool free_newunit = false;
  finalize_transfer (dtp);

  if (dtp->u.p.current_unit != NULL
      && dtp->u.p.current_unit->child_dtio == 0)
    {
      /* Deal with endfile conditions associated with sequential files.  */
      if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
	switch (dtp->u.p.current_unit->endfile)
	  {
	  case AT_ENDFILE:		/* Remain at the endfile record.  */
	    break;

	  case AFTER_ENDFILE:
	    dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now.  */
	    break;

	  case NO_ENDFILE:
	    /* Get rid of whatever is after this record.  */
	    if (!is_internal_unit (dtp))
	      unit_truncate (dtp->u.p.current_unit,
			     stell (dtp->u.p.current_unit->s),
			     &dtp->common);
	    dtp->u.p.current_unit->endfile = AT_ENDFILE;
	    break;
	  }

      free_ionml (dtp);

      /* If this is a parent WRITE statement we do not need to retain the
	 internal unit structure for child use.  */
      if (dtp->u.p.unit_is_internal)
	{
	  if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
	    {
	      free (dtp->u.p.current_unit->filename);
	      dtp->u.p.current_unit->filename = NULL;
	      free (dtp->u.p.current_unit->ls);
	      dtp->u.p.current_unit->ls = NULL;
	    }
	  free_newunit = true;
	}
      if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
	{
	  free_format_data (dtp->u.p.fmt);
	  free_format (dtp);
	}
    }
   if (unlock)
     unlock_unit (dtp->u.p.current_unit);
   if (free_newunit)
     {
       /* Avoid inverse lock issues by placing after unlock_unit.  */
       WRLOCK (&unit_rwlock);
       newunit_free (dtp->common.unit);
       RWUNLOCK (&unit_rwlock);
     }
}

extern void st_write_done (st_parameter_dt *);
export_proto(st_write_done);

void
st_write_done (st_parameter_dt *dtp)
{
  if (dtp->u.p.current_unit)
    {
      if (dtp->u.p.current_unit->au && dtp->u.p.async)
	{
	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
					AIO_WRITE_DONE);
	  else
	    {
	      /* We perform synchronous I/O on an asynchronous unit, so no need
		 to enqueue AIO_READ_DONE.  */
	      if (dtp->u.p.async)
		enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
	    }
	  unlock_unit (dtp->u.p.current_unit);
	}
      else
	st_write_done_worker (dtp, true);  /* Calls unlock_unit.  */
    }

  library_end ();
}

/* Wait operation.  We need to keep around the do-nothing version
 of st_wait for compatibility with previous versions, which had marked
 the argument as unused (and thus liable to be removed).

 TODO: remove at next bump in version number.  */

void
st_wait (st_parameter_wait *wtp __attribute__((unused)))
{
  return;
}

void
st_wait_async (st_parameter_wait *wtp)
{
  gfc_unit *u = find_unit (wtp->common.unit);
  if (ASYNC_IO && u && u->au)
    {
      if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
	async_wait_id (&(wtp->common), u->au, *wtp->id);
      else
	async_wait (&(wtp->common), u->au);
    }

  unlock_unit (u);
}


/* Receives the scalar information for namelist objects and stores it
   in a linked list of namelist_info types.  */

static void
set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
	     GFC_INTEGER_4 len, gfc_charlen_type string_length,
	     dtype_type dtype, void *dtio_sub, void *vtable)
{
  namelist_info *t1 = NULL;
  namelist_info *nml;
  size_t var_name_len = strlen (var_name);

  nml = (namelist_info*) xmalloc (sizeof (namelist_info));

  nml->mem_pos = var_addr;
  nml->dtio_sub = dtio_sub;
  nml->vtable = vtable;

  nml->var_name = (char*) xmalloc (var_name_len + 1);
  memcpy (nml->var_name, var_name, var_name_len);
  nml->var_name[var_name_len] = '\0';

  nml->len = (int) len;
  nml->string_length = (index_type) string_length;

  nml->var_rank = (int) (dtype.rank);
  nml->size = (index_type) (dtype.elem_len);
  nml->type = (bt) (dtype.type);

  if (nml->var_rank > 0)
    {
      nml->dim = (descriptor_dimension*)
	xmallocarray (nml->var_rank, sizeof (descriptor_dimension));
      nml->ls = (array_loop_spec*)
	xmallocarray (nml->var_rank, sizeof (array_loop_spec));
    }
  else
    {
      nml->dim = NULL;
      nml->ls = NULL;
    }

  nml->next = NULL;

  if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
    {
      dtp->common.flags |= IOPARM_DT_IONML_SET;
      dtp->u.p.ionml = nml;
    }
  else
    {
      for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
      t1->next = nml;
    }
}

extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
			    GFC_INTEGER_4, gfc_charlen_type, dtype_type);
export_proto(st_set_nml_var);

void
st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
		GFC_INTEGER_4 len, gfc_charlen_type string_length,
		dtype_type dtype)
{
  set_nml_var (dtp, var_addr, var_name, len, string_length,
	       dtype, NULL, NULL);
}


/* Essentially the same as previous but carrying the dtio procedure
   and the vtable as additional arguments.  */
extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
				 GFC_INTEGER_4, gfc_charlen_type, dtype_type,
				 void *, void *);
export_proto(st_set_nml_dtio_var);


void
st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
		     GFC_INTEGER_4 len, gfc_charlen_type string_length,
		     dtype_type dtype, void *dtio_sub, void *vtable)
{
  set_nml_var (dtp, var_addr, var_name, len, string_length,
	       dtype, dtio_sub, vtable);
}

/* Store the dimensional information for the namelist object.  */
extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
				index_type, index_type,
				index_type);
export_proto(st_set_nml_var_dim);

void
st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
		    index_type stride, index_type lbound,
		    index_type ubound)
{
  namelist_info *nml;
  int n;

  n = (int)n_dim;

  for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);

  GFC_DIMENSION_SET(nml->dim[n],lbound,ubound,stride);
}


/* Once upon a time, a poor innocent Fortran program was reading a
   file, when suddenly it hit the end-of-file (EOF).  Unfortunately
   the OS doesn't tell whether we're at the EOF or whether we already
   went past it.  Luckily our hero, libgfortran, keeps track of this.
   Call this function when you detect an EOF condition.  See Section
   9.10.2 in F2003.  */

void
hit_eof (st_parameter_dt *dtp)
{
  dtp->u.p.current_unit->flags.position = POSITION_APPEND;

  if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
    switch (dtp->u.p.current_unit->endfile)
      {
      case NO_ENDFILE:
      case AT_ENDFILE:
        generate_error (&dtp->common, LIBERROR_END, NULL);
	if (!is_internal_unit (dtp) && !dtp->u.p.namelist_mode)
	  {
	    dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
	    dtp->u.p.current_unit->current_record = 0;
	  }
        else
          dtp->u.p.current_unit->endfile = AT_ENDFILE;
	break;

      case AFTER_ENDFILE:
	generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
	dtp->u.p.current_unit->current_record = 0;
	break;
      }
  else
    {
      /* Non-sequential files don't have an ENDFILE record, so we
         can't be at AFTER_ENDFILE.  */
      dtp->u.p.current_unit->endfile = AT_ENDFILE;
      generate_error (&dtp->common, LIBERROR_END, NULL);
      dtp->u.p.current_unit->current_record = 0;
    }
}
