Home | History | Annotate | Line # | Download | only in io
transfer.c revision 1.1.1.1
      1 /* Copyright (C) 2002-2019 Free Software Foundation, Inc.
      2    Contributed by Andy Vaught
      3    Namelist transfer functions contributed by Paul Thomas
      4    F2003 I/O support contributed by Jerry DeLisle
      5 
      6 This file is part of the GNU Fortran runtime library (libgfortran).
      7 
      8 Libgfortran is free software; you can redistribute it and/or modify
      9 it under the terms of the GNU General Public License as published by
     10 the Free Software Foundation; either version 3, or (at your option)
     11 any later version.
     12 
     13 Libgfortran is distributed in the hope that it will be useful,
     14 but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 GNU General Public License for more details.
     17 
     18 Under Section 7 of GPL version 3, you are granted additional
     19 permissions described in the GCC Runtime Library Exception, version
     20 3.1, as published by the Free Software Foundation.
     21 
     22 You should have received a copy of the GNU General Public License and
     23 a copy of the GCC Runtime Library Exception along with this program;
     24 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     25 <http://www.gnu.org/licenses/>.  */
     26 
     27 
     28 /* transfer.c -- Top level handling of data transfer statements.  */
     29 
     30 #include "io.h"
     31 #include "fbuf.h"
     32 #include "format.h"
     33 #include "unix.h"
     34 #include "async.h"
     35 #include <string.h>
     36 #include <errno.h>
     37 
     38 
     39 /* Calling conventions:  Data transfer statements are unlike other
     40    library calls in that they extend over several calls.
     41 
     42    The first call is always a call to st_read() or st_write().  These
     43    subroutines return no status unless a namelist read or write is
     44    being done, in which case there is the usual status.  No further
     45    calls are necessary in this case.
     46 
     47    For other sorts of data transfer, there are zero or more data
     48    transfer statement that depend on the format of the data transfer
     49    statement. For READ (and for backwards compatibily: for WRITE), one has
     50 
     51       transfer_integer
     52       transfer_logical
     53       transfer_character
     54       transfer_character_wide
     55       transfer_real
     56       transfer_complex
     57       transfer_real128
     58       transfer_complex128
     59 
     60     and for WRITE
     61 
     62       transfer_integer_write
     63       transfer_logical_write
     64       transfer_character_write
     65       transfer_character_wide_write
     66       transfer_real_write
     67       transfer_complex_write
     68       transfer_real128_write
     69       transfer_complex128_write
     70 
     71     These subroutines do not return status. The *128 functions
     72     are in the file transfer128.c.
     73 
     74     The last call is a call to st_[read|write]_done().  While
     75     something can easily go wrong with the initial st_read() or
     76     st_write(), an error inhibits any data from actually being
     77     transferred.  */
     78 
     79 extern void transfer_integer (st_parameter_dt *, void *, int);
     80 export_proto(transfer_integer);
     81 
     82 extern void transfer_integer_write (st_parameter_dt *, void *, int);
     83 export_proto(transfer_integer_write);
     84 
     85 extern void transfer_real (st_parameter_dt *, void *, int);
     86 export_proto(transfer_real);
     87 
     88 extern void transfer_real_write (st_parameter_dt *, void *, int);
     89 export_proto(transfer_real_write);
     90 
     91 extern void transfer_logical (st_parameter_dt *, void *, int);
     92 export_proto(transfer_logical);
     93 
     94 extern void transfer_logical_write (st_parameter_dt *, void *, int);
     95 export_proto(transfer_logical_write);
     96 
     97 extern void transfer_character (st_parameter_dt *, void *, gfc_charlen_type);
     98 export_proto(transfer_character);
     99 
    100 extern void transfer_character_write (st_parameter_dt *, void *, gfc_charlen_type);
    101 export_proto(transfer_character_write);
    102 
    103 extern void transfer_character_wide (st_parameter_dt *, void *, gfc_charlen_type, int);
    104 export_proto(transfer_character_wide);
    105 
    106 extern void transfer_character_wide_write (st_parameter_dt *,
    107 					   void *, gfc_charlen_type, int);
    108 export_proto(transfer_character_wide_write);
    109 
    110 extern void transfer_complex (st_parameter_dt *, void *, int);
    111 export_proto(transfer_complex);
    112 
    113 extern void transfer_complex_write (st_parameter_dt *, void *, int);
    114 export_proto(transfer_complex_write);
    115 
    116 extern void transfer_array (st_parameter_dt *, gfc_array_char *, int,
    117 			    gfc_charlen_type);
    118 export_proto(transfer_array);
    119 
    120 extern void transfer_array_write (st_parameter_dt *, gfc_array_char *, int,
    121 			    gfc_charlen_type);
    122 export_proto(transfer_array_write);
    123 
    124 /* User defined derived type input/output.  */
    125 extern void
    126 transfer_derived (st_parameter_dt *dtp, void *dtio_source, void *dtio_proc);
    127 export_proto(transfer_derived);
    128 
    129 extern void
    130 transfer_derived_write (st_parameter_dt *dtp, void *dtio_source, void *dtio_proc);
    131 export_proto(transfer_derived_write);
    132 
    133 static void us_read (st_parameter_dt *, int);
    134 static void us_write (st_parameter_dt *, int);
    135 static void next_record_r_unf (st_parameter_dt *, int);
    136 static void next_record_w_unf (st_parameter_dt *, int);
    137 
    138 static const st_option advance_opt[] = {
    139   {"yes", ADVANCE_YES},
    140   {"no", ADVANCE_NO},
    141   {NULL, 0}
    142 };
    143 
    144 
    145 static const st_option decimal_opt[] = {
    146   {"point", DECIMAL_POINT},
    147   {"comma", DECIMAL_COMMA},
    148   {NULL, 0}
    149 };
    150 
    151 static const st_option round_opt[] = {
    152   {"up", ROUND_UP},
    153   {"down", ROUND_DOWN},
    154   {"zero", ROUND_ZERO},
    155   {"nearest", ROUND_NEAREST},
    156   {"compatible", ROUND_COMPATIBLE},
    157   {"processor_defined", ROUND_PROCDEFINED},
    158   {NULL, 0}
    159 };
    160 
    161 
    162 static const st_option sign_opt[] = {
    163   {"plus", SIGN_SP},
    164   {"suppress", SIGN_SS},
    165   {"processor_defined", SIGN_S},
    166   {NULL, 0}
    167 };
    168 
    169 static const st_option blank_opt[] = {
    170   {"null", BLANK_NULL},
    171   {"zero", BLANK_ZERO},
    172   {NULL, 0}
    173 };
    174 
    175 static const st_option delim_opt[] = {
    176   {"apostrophe", DELIM_APOSTROPHE},
    177   {"quote", DELIM_QUOTE},
    178   {"none", DELIM_NONE},
    179   {NULL, 0}
    180 };
    181 
    182 static const st_option pad_opt[] = {
    183   {"yes", PAD_YES},
    184   {"no", PAD_NO},
    185   {NULL, 0}
    186 };
    187 
    188 static const st_option async_opt[] = {
    189   {"yes", ASYNC_YES},
    190   {"no", ASYNC_NO},
    191   {NULL, 0}
    192 };
    193 
    194 typedef enum
    195 { FORMATTED_SEQUENTIAL, UNFORMATTED_SEQUENTIAL,
    196   FORMATTED_DIRECT, UNFORMATTED_DIRECT, FORMATTED_STREAM, UNFORMATTED_STREAM
    197 }
    198 file_mode;
    199 
    200 
    201 static file_mode
    202 current_mode (st_parameter_dt *dtp)
    203 {
    204   file_mode m;
    205 
    206   m = FORM_UNSPECIFIED;
    207 
    208   if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
    209     {
    210       m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
    211 	FORMATTED_DIRECT : UNFORMATTED_DIRECT;
    212     }
    213   else if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
    214     {
    215       m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
    216 	FORMATTED_SEQUENTIAL : UNFORMATTED_SEQUENTIAL;
    217     }
    218   else if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
    219     {
    220       m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
    221 	FORMATTED_STREAM : UNFORMATTED_STREAM;
    222     }
    223 
    224   return m;
    225 }
    226 
    227 
    228 /* Mid level data transfer statements.  */
    229 
    230 /* Read sequential file - internal unit  */
    231 
    232 static char *
    233 read_sf_internal (st_parameter_dt *dtp, size_t *length)
    234 {
    235   static char *empty_string[0];
    236   char *base = NULL;
    237   size_t lorig;
    238 
    239   /* Zero size array gives internal unit len of 0.  Nothing to read. */
    240   if (dtp->internal_unit_len == 0
    241       && dtp->u.p.current_unit->pad_status == PAD_NO)
    242     hit_eof (dtp);
    243 
    244   /* There are some cases with mixed DTIO where we have read a character
    245      and saved it in the last character buffer, so we need to backup.  */
    246   if (unlikely (dtp->u.p.current_unit->child_dtio > 0 &&
    247 		dtp->u.p.current_unit->last_char != EOF - 1))
    248     {
    249       dtp->u.p.current_unit->last_char = EOF - 1;
    250       sseek (dtp->u.p.current_unit->s, -1, SEEK_CUR);
    251     }
    252 
    253   /* To support legacy code we have to scan the input string one byte
    254      at a time because we don't know where an early comma may be and the
    255      requested length could go past the end of a comma shortened
    256      string.  We only do this if -std=legacy was given at compile
    257      time.  We also do not support this on kind=4 strings.  */
    258   if (unlikely(compile_options.warn_std == 0)) // the slow legacy way.
    259     {
    260       size_t n;
    261       size_t tmp = 1;
    262       char *q;
    263 
    264       /* If we have seen an eor previously, return a length of 0.  The
    265 	 caller is responsible for correctly padding the input field.  */
    266       if (dtp->u.p.sf_seen_eor)
    267 	{
    268 	  *length = 0;
    269 	  /* Just return something that isn't a NULL pointer, otherwise the
    270 	     caller thinks an error occurred.  */
    271 	  return (char*) empty_string;
    272 	}
    273 
    274       /* Get the first character of the string to establish the base
    275 	 address and check for comma or end-of-record condition.  */
    276       base = mem_alloc_r (dtp->u.p.current_unit->s, &tmp);
    277       if (tmp == 0)
    278 	{
    279 	  dtp->u.p.sf_seen_eor = 1;
    280 	  *length = 0;
    281 	  return (char*) empty_string;
    282 	}
    283       if (*base == ',')
    284 	{
    285 	  dtp->u.p.current_unit->bytes_left--;
    286 	  *length = 0;
    287 	  return (char*) empty_string;
    288 	}
    289 
    290       /* Now we scan the rest and deal with either an end-of-file
    291          condition or a comma, as needed.  */
    292       for (n = 1; n < *length; n++)
    293 	{
    294 	  q = mem_alloc_r (dtp->u.p.current_unit->s, &tmp);
    295 	  if (tmp == 0)
    296 	    {
    297 	      hit_eof (dtp);
    298 	      return NULL;
    299 	    }
    300 	  if (*q == ',')
    301 	    {
    302 	      dtp->u.p.current_unit->bytes_left -= n;
    303 	      *length = n;
    304 	      break;
    305 	    }
    306 	}
    307     }
    308   else // the fast way
    309     {
    310       lorig = *length;
    311       if (is_char4_unit(dtp))
    312 	{
    313 	  gfc_char4_t *p = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s,
    314 			    length);
    315 	  base = fbuf_alloc (dtp->u.p.current_unit, lorig);
    316 	  for (size_t i = 0; i < *length; i++, p++)
    317 	    base[i] = *p > 255 ? '?' : (unsigned char) *p;
    318 	}
    319       else
    320 	base = mem_alloc_r (dtp->u.p.current_unit->s, length);
    321 
    322       if (unlikely (lorig > *length))
    323 	{
    324 	  hit_eof (dtp);
    325 	  return NULL;
    326 	}
    327     }
    328 
    329   dtp->u.p.current_unit->bytes_left -= *length;
    330 
    331   if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
    332       dtp->u.p.current_unit->has_size)
    333     dtp->u.p.current_unit->size_used += (GFC_IO_INT) *length;
    334 
    335   return base;
    336 
    337 }
    338 
    339 /* When reading sequential formatted records we have a problem.  We
    340    don't know how long the line is until we read the trailing newline,
    341    and we don't want to read too much.  If we read too much, we might
    342    have to do a physical seek backwards depending on how much data is
    343    present, and devices like terminals aren't seekable and would cause
    344    an I/O error.
    345 
    346    Given this, the solution is to read a byte at a time, stopping if
    347    we hit the newline.  For small allocations, we use a static buffer.
    348    For larger allocations, we are forced to allocate memory on the
    349    heap.  Hopefully this won't happen very often.  */
    350 
    351 /* Read sequential file - external unit */
    352 
    353 static char *
    354 read_sf (st_parameter_dt *dtp, size_t *length)
    355 {
    356   static char *empty_string[0];
    357   size_t lorig, n;
    358   int q, q2;
    359   int seen_comma;
    360 
    361   /* If we have seen an eor previously, return a length of 0.  The
    362      caller is responsible for correctly padding the input field.  */
    363   if (dtp->u.p.sf_seen_eor)
    364     {
    365       *length = 0;
    366       /* Just return something that isn't a NULL pointer, otherwise the
    367          caller thinks an error occurred.  */
    368       return (char*) empty_string;
    369     }
    370 
    371   /* There are some cases with mixed DTIO where we have read a character
    372      and saved it in the last character buffer, so we need to backup.  */
    373   if (unlikely (dtp->u.p.current_unit->child_dtio > 0 &&
    374 		dtp->u.p.current_unit->last_char != EOF - 1))
    375     {
    376       dtp->u.p.current_unit->last_char = EOF - 1;
    377       fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
    378     }
    379 
    380   n = seen_comma = 0;
    381 
    382   /* Read data into format buffer and scan through it.  */
    383   lorig = *length;
    384 
    385   while (n < *length)
    386     {
    387       q = fbuf_getc (dtp->u.p.current_unit);
    388       if (q == EOF)
    389 	break;
    390       else if (dtp->u.p.current_unit->flags.cc != CC_NONE
    391 	       && (q == '\n' || q == '\r'))
    392 	{
    393 	  /* Unexpected end of line. Set the position.  */
    394 	  dtp->u.p.sf_seen_eor = 1;
    395 
    396 	  /* If we see an EOR during non-advancing I/O, we need to skip
    397 	     the rest of the I/O statement.  Set the corresponding flag.  */
    398 	  if (dtp->u.p.advance_status == ADVANCE_NO || dtp->u.p.seen_dollar)
    399 	    dtp->u.p.eor_condition = 1;
    400 
    401 	  /* If we encounter a CR, it might be a CRLF.  */
    402 	  if (q == '\r') /* Probably a CRLF */
    403 	    {
    404 	      /* See if there is an LF.  */
    405 	      q2 = fbuf_getc (dtp->u.p.current_unit);
    406 	      if (q2 == '\n')
    407 		dtp->u.p.sf_seen_eor = 2;
    408 	      else if (q2 != EOF) /* Oops, seek back.  */
    409 		fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
    410 	    }
    411 
    412 	  /* Without padding, terminate the I/O statement without assigning
    413 	     the value.  With padding, the value still needs to be assigned,
    414 	     so we can just continue with a short read.  */
    415 	  if (dtp->u.p.current_unit->pad_status == PAD_NO)
    416 	    {
    417 	      generate_error (&dtp->common, LIBERROR_EOR, NULL);
    418 	      return NULL;
    419 	    }
    420 
    421 	  *length = n;
    422 	  goto done;
    423 	}
    424       /*  Short circuit the read if a comma is found during numeric input.
    425 	  The flag is set to zero during character reads so that commas in
    426 	  strings are not ignored  */
    427       else if (q == ',')
    428 	if (dtp->u.p.sf_read_comma == 1)
    429 	  {
    430             seen_comma = 1;
    431 	    notify_std (&dtp->common, GFC_STD_GNU,
    432 			"Comma in formatted numeric read.");
    433 	    break;
    434 	  }
    435       n++;
    436     }
    437 
    438   *length = n;
    439 
    440   /* A short read implies we hit EOF, unless we hit EOR, a comma, or
    441      some other stuff. Set the relevant flags.  */
    442   if (lorig > *length && !dtp->u.p.sf_seen_eor && !seen_comma)
    443     {
    444       if (n > 0)
    445         {
    446 	  if (dtp->u.p.advance_status == ADVANCE_NO)
    447 	    {
    448 	      if (dtp->u.p.current_unit->pad_status == PAD_NO)
    449 	        {
    450 		  hit_eof (dtp);
    451 		  return NULL;
    452 		}
    453 	      else
    454 		dtp->u.p.eor_condition = 1;
    455 	    }
    456 	  else
    457 	    dtp->u.p.at_eof = 1;
    458 	}
    459       else if (dtp->u.p.advance_status == ADVANCE_NO
    460 	       || dtp->u.p.current_unit->pad_status == PAD_NO
    461 	       || dtp->u.p.current_unit->bytes_left
    462 		    == dtp->u.p.current_unit->recl)
    463 	{
    464 	  hit_eof (dtp);
    465 	  return NULL;
    466 	}
    467     }
    468 
    469  done:
    470 
    471   dtp->u.p.current_unit->bytes_left -= n;
    472 
    473   if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
    474       dtp->u.p.current_unit->has_size)
    475     dtp->u.p.current_unit->size_used += (GFC_IO_INT) n;
    476 
    477   /* We can't call fbuf_getptr before the loop doing fbuf_getc, because
    478      fbuf_getc might reallocate the buffer.  So return current pointer
    479      minus all the advances, which is n plus up to two characters
    480      of newline or comma.  */
    481   return fbuf_getptr (dtp->u.p.current_unit)
    482 	 - n - dtp->u.p.sf_seen_eor - seen_comma;
    483 }
    484 
    485 
    486 /* Function for reading the next couple of bytes from the current
    487    file, advancing the current position. We return NULL on end of record or
    488    end of file. This function is only for formatted I/O, unformatted uses
    489    read_block_direct.
    490 
    491    If the read is short, then it is because the current record does not
    492    have enough data to satisfy the read request and the file was
    493    opened with PAD=YES.  The caller must assume tailing spaces for
    494    short reads.  */
    495 
    496 void *
    497 read_block_form (st_parameter_dt *dtp, size_t *nbytes)
    498 {
    499   char *source;
    500   size_t norig;
    501 
    502   if (!is_stream_io (dtp))
    503     {
    504       if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
    505 	{
    506 	  /* For preconnected units with default record length, set bytes left
    507 	   to unit record length and proceed, otherwise error.  */
    508 	  if (dtp->u.p.current_unit->unit_number == options.stdin_unit
    509 	      && dtp->u.p.current_unit->recl == default_recl)
    510             dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
    511 	  else
    512 	    {
    513 	      if (unlikely (dtp->u.p.current_unit->pad_status == PAD_NO)
    514 		  && !is_internal_unit (dtp))
    515 		{
    516 		  /* Not enough data left.  */
    517 		  generate_error (&dtp->common, LIBERROR_EOR, NULL);
    518 		  return NULL;
    519 		}
    520 	    }
    521 
    522 	  if (is_internal_unit(dtp))
    523 	    {
    524 	      if (*nbytes > 0 && dtp->u.p.current_unit->bytes_left == 0)
    525 	        {
    526 		  if (dtp->u.p.advance_status == ADVANCE_NO)
    527 		    {
    528 		      generate_error (&dtp->common, LIBERROR_EOR, NULL);
    529 		      return NULL;
    530 		    }
    531 		}
    532 	    }
    533 	  else
    534 	    {
    535 	      if (unlikely (dtp->u.p.current_unit->bytes_left == 0))
    536 		{
    537 		  hit_eof (dtp);
    538 		  return NULL;
    539 		}
    540 	    }
    541 
    542 	  *nbytes = dtp->u.p.current_unit->bytes_left;
    543 	}
    544     }
    545 
    546   if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
    547       (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL ||
    548        dtp->u.p.current_unit->flags.access == ACCESS_STREAM))
    549     {
    550       if (is_internal_unit (dtp))
    551 	source = read_sf_internal (dtp, nbytes);
    552       else
    553 	source = read_sf (dtp, nbytes);
    554 
    555       dtp->u.p.current_unit->strm_pos +=
    556 	(gfc_offset) (*nbytes + dtp->u.p.sf_seen_eor);
    557       return source;
    558     }
    559 
    560   /* If we reach here, we can assume it's direct access.  */
    561 
    562   dtp->u.p.current_unit->bytes_left -= (gfc_offset) *nbytes;
    563 
    564   norig = *nbytes;
    565   source = fbuf_read (dtp->u.p.current_unit, nbytes);
    566   fbuf_seek (dtp->u.p.current_unit, *nbytes, SEEK_CUR);
    567 
    568   if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
    569       dtp->u.p.current_unit->has_size)
    570     dtp->u.p.current_unit->size_used += (GFC_IO_INT) *nbytes;
    571 
    572   if (norig != *nbytes)
    573     {
    574       /* Short read, this shouldn't happen.  */
    575       if (dtp->u.p.current_unit->pad_status == PAD_NO)
    576 	{
    577 	  generate_error (&dtp->common, LIBERROR_EOR, NULL);
    578 	  source = NULL;
    579 	}
    580     }
    581 
    582   dtp->u.p.current_unit->strm_pos += (gfc_offset) *nbytes;
    583 
    584   return source;
    585 }
    586 
    587 
    588 /* Read a block from a character(kind=4) internal unit, to be transferred into
    589    a character(kind=4) variable.  Note: Portions of this code borrowed from
    590    read_sf_internal.  */
    591 void *
    592 read_block_form4 (st_parameter_dt *dtp, size_t *nbytes)
    593 {
    594   static gfc_char4_t *empty_string[0];
    595   gfc_char4_t *source;
    596   size_t lorig;
    597 
    598   if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
    599     *nbytes = dtp->u.p.current_unit->bytes_left;
    600 
    601   /* Zero size array gives internal unit len of 0.  Nothing to read. */
    602   if (dtp->internal_unit_len == 0
    603       && dtp->u.p.current_unit->pad_status == PAD_NO)
    604     hit_eof (dtp);
    605 
    606   /* If we have seen an eor previously, return a length of 0.  The
    607      caller is responsible for correctly padding the input field.  */
    608   if (dtp->u.p.sf_seen_eor)
    609     {
    610       *nbytes = 0;
    611       /* Just return something that isn't a NULL pointer, otherwise the
    612          caller thinks an error occurred.  */
    613       return empty_string;
    614     }
    615 
    616   lorig = *nbytes;
    617   source = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s, nbytes);
    618 
    619   if (unlikely (lorig > *nbytes))
    620     {
    621       hit_eof (dtp);
    622       return NULL;
    623     }
    624 
    625   dtp->u.p.current_unit->bytes_left -= *nbytes;
    626 
    627   if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
    628       dtp->u.p.current_unit->has_size)
    629     dtp->u.p.current_unit->size_used += (GFC_IO_INT) *nbytes;
    630 
    631   return source;
    632 }
    633 
    634 
    635 /* Reads a block directly into application data space.  This is for
    636    unformatted files.  */
    637 
    638 static void
    639 read_block_direct (st_parameter_dt *dtp, void *buf, size_t nbytes)
    640 {
    641   ssize_t to_read_record;
    642   ssize_t have_read_record;
    643   ssize_t to_read_subrecord;
    644   ssize_t have_read_subrecord;
    645   int short_record;
    646 
    647   if (is_stream_io (dtp))
    648     {
    649       have_read_record = sread (dtp->u.p.current_unit->s, buf,
    650 				nbytes);
    651       if (unlikely (have_read_record < 0))
    652 	{
    653 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    654 	  return;
    655 	}
    656 
    657       dtp->u.p.current_unit->strm_pos += (gfc_offset) have_read_record;
    658 
    659       if (unlikely ((ssize_t) nbytes != have_read_record))
    660 	{
    661 	  /* Short read,  e.g. if we hit EOF.  For stream files,
    662 	   we have to set the end-of-file condition.  */
    663           hit_eof (dtp);
    664 	}
    665       return;
    666     }
    667 
    668   if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
    669     {
    670       if (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes)
    671 	{
    672 	  short_record = 1;
    673 	  to_read_record = dtp->u.p.current_unit->bytes_left;
    674 	  nbytes = to_read_record;
    675 	}
    676       else
    677 	{
    678 	  short_record = 0;
    679 	  to_read_record = nbytes;
    680 	}
    681 
    682       dtp->u.p.current_unit->bytes_left -= to_read_record;
    683 
    684       to_read_record = sread (dtp->u.p.current_unit->s, buf, to_read_record);
    685       if (unlikely (to_read_record < 0))
    686 	{
    687 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    688 	  return;
    689 	}
    690 
    691       if (to_read_record != (ssize_t) nbytes)
    692 	{
    693 	  /* Short read, e.g. if we hit EOF.  Apparently, we read
    694 	   more than was written to the last record.  */
    695 	  return;
    696 	}
    697 
    698       if (unlikely (short_record))
    699 	{
    700 	  generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
    701 	}
    702       return;
    703     }
    704 
    705   /* Unformatted sequential.  We loop over the subrecords, reading
    706      until the request has been fulfilled or the record has run out
    707      of continuation subrecords.  */
    708 
    709   /* Check whether we exceed the total record length.  */
    710 
    711   if (dtp->u.p.current_unit->flags.has_recl
    712       && ((gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left))
    713     {
    714       to_read_record = dtp->u.p.current_unit->bytes_left;
    715       short_record = 1;
    716     }
    717   else
    718     {
    719       to_read_record = nbytes;
    720       short_record = 0;
    721     }
    722   have_read_record = 0;
    723 
    724   while(1)
    725     {
    726       if (dtp->u.p.current_unit->bytes_left_subrecord
    727 	  < (gfc_offset) to_read_record)
    728 	{
    729 	  to_read_subrecord = dtp->u.p.current_unit->bytes_left_subrecord;
    730 	  to_read_record -= to_read_subrecord;
    731 	}
    732       else
    733 	{
    734 	  to_read_subrecord = to_read_record;
    735 	  to_read_record = 0;
    736 	}
    737 
    738       dtp->u.p.current_unit->bytes_left_subrecord -= to_read_subrecord;
    739 
    740       have_read_subrecord = sread (dtp->u.p.current_unit->s,
    741 				   buf + have_read_record, to_read_subrecord);
    742       if (unlikely (have_read_subrecord < 0))
    743 	{
    744 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    745 	  return;
    746 	}
    747 
    748       have_read_record += have_read_subrecord;
    749 
    750       if (unlikely (to_read_subrecord != have_read_subrecord))
    751 	{
    752 	  /* Short read, e.g. if we hit EOF.  This means the record
    753 	     structure has been corrupted, or the trailing record
    754 	     marker would still be present.  */
    755 
    756 	  generate_error (&dtp->common, LIBERROR_CORRUPT_FILE, NULL);
    757 	  return;
    758 	}
    759 
    760       if (to_read_record > 0)
    761 	{
    762 	  if (likely (dtp->u.p.current_unit->continued))
    763 	    {
    764 	      next_record_r_unf (dtp, 0);
    765 	      us_read (dtp, 1);
    766 	    }
    767 	  else
    768 	    {
    769 	      /* Let's make sure the file position is correctly pre-positioned
    770 		 for the next read statement.  */
    771 
    772 	      dtp->u.p.current_unit->current_record = 0;
    773 	      next_record_r_unf (dtp, 0);
    774 	      generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
    775 	      return;
    776 	    }
    777 	}
    778       else
    779 	{
    780 	  /* Normal exit, the read request has been fulfilled.  */
    781 	  break;
    782 	}
    783     }
    784 
    785   dtp->u.p.current_unit->bytes_left -= have_read_record;
    786   if (unlikely (short_record))
    787     {
    788       generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
    789       return;
    790     }
    791   return;
    792 }
    793 
    794 
    795 /* Function for writing a block of bytes to the current file at the
    796    current position, advancing the file pointer. We are given a length
    797    and return a pointer to a buffer that the caller must (completely)
    798    fill in.  Returns NULL on error.  */
    799 
    800 void *
    801 write_block (st_parameter_dt *dtp, size_t length)
    802 {
    803   char *dest;
    804 
    805   if (!is_stream_io (dtp))
    806     {
    807       if (dtp->u.p.current_unit->bytes_left < (gfc_offset) length)
    808 	{
    809 	  /* For preconnected units with default record length, set bytes left
    810 	     to unit record length and proceed, otherwise error.  */
    811 	  if (likely ((dtp->u.p.current_unit->unit_number
    812 		       == options.stdout_unit
    813 		       || dtp->u.p.current_unit->unit_number
    814 		       == options.stderr_unit)
    815 		      && dtp->u.p.current_unit->recl == default_recl))
    816 	    dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
    817 	  else
    818 	    {
    819 	      generate_error (&dtp->common, LIBERROR_EOR, NULL);
    820 	      return NULL;
    821 	    }
    822 	}
    823 
    824       dtp->u.p.current_unit->bytes_left -= (gfc_offset) length;
    825     }
    826 
    827   if (is_internal_unit (dtp))
    828     {
    829       if (is_char4_unit(dtp)) /* char4 internel unit.  */
    830 	{
    831 	  gfc_char4_t *dest4;
    832 	  dest4 = mem_alloc_w4 (dtp->u.p.current_unit->s, &length);
    833 	  if (dest4 == NULL)
    834 	  {
    835             generate_error (&dtp->common, LIBERROR_END, NULL);
    836             return NULL;
    837 	  }
    838 	  return dest4;
    839 	}
    840       else
    841 	dest = mem_alloc_w (dtp->u.p.current_unit->s, &length);
    842 
    843       if (dest == NULL)
    844 	{
    845           generate_error (&dtp->common, LIBERROR_END, NULL);
    846           return NULL;
    847 	}
    848 
    849       if (unlikely (dtp->u.p.current_unit->endfile == AT_ENDFILE))
    850 	generate_error (&dtp->common, LIBERROR_END, NULL);
    851     }
    852   else
    853     {
    854       dest = fbuf_alloc (dtp->u.p.current_unit, length);
    855       if (dest == NULL)
    856 	{
    857 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    858 	  return NULL;
    859 	}
    860     }
    861 
    862   if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
    863       dtp->u.p.current_unit->has_size)
    864     dtp->u.p.current_unit->size_used += (GFC_IO_INT) length;
    865 
    866   dtp->u.p.current_unit->strm_pos += (gfc_offset) length;
    867 
    868   return dest;
    869 }
    870 
    871 
    872 /* High level interface to swrite(), taking care of errors.  This is only
    873    called for unformatted files.  There are three cases to consider:
    874    Stream I/O, unformatted direct, unformatted sequential.  */
    875 
    876 static bool
    877 write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
    878 {
    879 
    880   ssize_t have_written;
    881   ssize_t to_write_subrecord;
    882   int short_record;
    883 
    884   /* Stream I/O.  */
    885 
    886   if (is_stream_io (dtp))
    887     {
    888       have_written = swrite (dtp->u.p.current_unit->s, buf, nbytes);
    889       if (unlikely (have_written < 0))
    890 	{
    891 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    892 	  return false;
    893 	}
    894 
    895       dtp->u.p.current_unit->strm_pos += (gfc_offset) have_written;
    896 
    897       return true;
    898     }
    899 
    900   /* Unformatted direct access.  */
    901 
    902   if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
    903     {
    904       if (unlikely (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes))
    905 	{
    906 	  generate_error (&dtp->common, LIBERROR_DIRECT_EOR, NULL);
    907 	  return false;
    908 	}
    909 
    910       if (buf == NULL && nbytes == 0)
    911 	return true;
    912 
    913       have_written = swrite (dtp->u.p.current_unit->s, buf, nbytes);
    914       if (unlikely (have_written < 0))
    915 	{
    916 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    917 	  return false;
    918 	}
    919 
    920       dtp->u.p.current_unit->strm_pos += (gfc_offset) have_written;
    921       dtp->u.p.current_unit->bytes_left -= (gfc_offset) have_written;
    922 
    923       return true;
    924     }
    925 
    926   /* Unformatted sequential.  */
    927 
    928   have_written = 0;
    929 
    930   if (dtp->u.p.current_unit->flags.has_recl
    931       && (gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left)
    932     {
    933       nbytes = dtp->u.p.current_unit->bytes_left;
    934       short_record = 1;
    935     }
    936   else
    937     {
    938       short_record = 0;
    939     }
    940 
    941   while (1)
    942     {
    943 
    944       to_write_subrecord =
    945 	(size_t) dtp->u.p.current_unit->bytes_left_subrecord < nbytes ?
    946 	(size_t) dtp->u.p.current_unit->bytes_left_subrecord : nbytes;
    947 
    948       dtp->u.p.current_unit->bytes_left_subrecord -=
    949 	(gfc_offset) to_write_subrecord;
    950 
    951       to_write_subrecord = swrite (dtp->u.p.current_unit->s,
    952 				   buf + have_written, to_write_subrecord);
    953       if (unlikely (to_write_subrecord < 0))
    954 	{
    955 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
    956 	  return false;
    957 	}
    958 
    959       dtp->u.p.current_unit->strm_pos += (gfc_offset) to_write_subrecord;
    960       nbytes -= to_write_subrecord;
    961       have_written += to_write_subrecord;
    962 
    963       if (nbytes == 0)
    964 	break;
    965 
    966       next_record_w_unf (dtp, 1);
    967       us_write (dtp, 1);
    968     }
    969   dtp->u.p.current_unit->bytes_left -= have_written;
    970   if (unlikely (short_record))
    971     {
    972       generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
    973       return false;
    974     }
    975   return true;
    976 }
    977 
    978 
    979 /* Reverse memcpy - used for byte swapping.  */
    980 
    981 static void
    982 reverse_memcpy (void *dest, const void *src, size_t n)
    983 {
    984   char *d, *s;
    985   size_t i;
    986 
    987   d = (char *) dest;
    988   s = (char *) src + n - 1;
    989 
    990   /* Write with ascending order - this is likely faster
    991      on modern architectures because of write combining.  */
    992   for (i=0; i<n; i++)
    993       *(d++) = *(s--);
    994 }
    995 
    996 
    997 /* Utility function for byteswapping an array, using the bswap
    998    builtins if possible. dest and src can overlap completely, or then
    999    they must point to separate objects; partial overlaps are not
   1000    allowed.  */
   1001 
   1002 static void
   1003 bswap_array (void *dest, const void *src, size_t size, size_t nelems)
   1004 {
   1005   const char *ps;
   1006   char *pd;
   1007 
   1008   switch (size)
   1009     {
   1010     case 1:
   1011       break;
   1012     case 2:
   1013       for (size_t i = 0; i < nelems; i++)
   1014 	((uint16_t*)dest)[i] = __builtin_bswap16 (((uint16_t*)src)[i]);
   1015       break;
   1016     case 4:
   1017       for (size_t i = 0; i < nelems; i++)
   1018 	((uint32_t*)dest)[i] = __builtin_bswap32 (((uint32_t*)src)[i]);
   1019       break;
   1020     case 8:
   1021       for (size_t i = 0; i < nelems; i++)
   1022 	((uint64_t*)dest)[i] = __builtin_bswap64 (((uint64_t*)src)[i]);
   1023       break;
   1024     case 12:
   1025       ps = src;
   1026       pd = dest;
   1027       for (size_t i = 0; i < nelems; i++)
   1028 	{
   1029 	  uint32_t tmp;
   1030 	  memcpy (&tmp, ps, 4);
   1031 	  *(uint32_t*)pd = __builtin_bswap32 (*(uint32_t*)(ps + 8));
   1032 	  *(uint32_t*)(pd + 4) = __builtin_bswap32 (*(uint32_t*)(ps + 4));
   1033 	  *(uint32_t*)(pd + 8) = __builtin_bswap32 (tmp);
   1034 	  ps += size;
   1035 	  pd += size;
   1036 	}
   1037       break;
   1038     case 16:
   1039       ps = src;
   1040       pd = dest;
   1041       for (size_t i = 0; i < nelems; i++)
   1042 	{
   1043 	  uint64_t tmp;
   1044 	  memcpy (&tmp, ps, 8);
   1045 	  *(uint64_t*)pd = __builtin_bswap64 (*(uint64_t*)(ps + 8));
   1046 	  *(uint64_t*)(pd + 8) = __builtin_bswap64 (tmp);
   1047 	  ps += size;
   1048 	  pd += size;
   1049 	}
   1050       break;
   1051     default:
   1052       pd = dest;
   1053       if (dest != src)
   1054 	{
   1055 	  ps = src;
   1056 	  for (size_t i = 0; i < nelems; i++)
   1057 	    {
   1058 	      reverse_memcpy (pd, ps, size);
   1059 	      ps += size;
   1060 	      pd += size;
   1061 	    }
   1062 	}
   1063       else
   1064 	{
   1065 	  /* In-place byte swap.  */
   1066 	  for (size_t i = 0; i < nelems; i++)
   1067 	    {
   1068 	      char tmp, *low = pd, *high = pd + size - 1;
   1069 	      for (size_t j = 0; j < size/2; j++)
   1070 		{
   1071 		  tmp = *low;
   1072 		  *low = *high;
   1073 		  *high = tmp;
   1074 		  low++;
   1075 		  high--;
   1076 		}
   1077 	      pd += size;
   1078 	    }
   1079 	}
   1080     }
   1081 }
   1082 
   1083 
   1084 /* Master function for unformatted reads.  */
   1085 
   1086 static void
   1087 unformatted_read (st_parameter_dt *dtp, bt type,
   1088 		  void *dest, int kind, size_t size, size_t nelems)
   1089 {
   1090   if (type == BT_CLASS)
   1091     {
   1092 	  int unit = dtp->u.p.current_unit->unit_number;
   1093 	  char tmp_iomsg[IOMSG_LEN] = "";
   1094 	  char *child_iomsg;
   1095 	  gfc_charlen_type child_iomsg_len;
   1096 	  int noiostat;
   1097 	  int *child_iostat = NULL;
   1098 
   1099 	  /* Set iostat, intent(out).  */
   1100 	  noiostat = 0;
   1101 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   1102 			  dtp->common.iostat : &noiostat;
   1103 
   1104 	  /* Set iomsg, intent(inout).  */
   1105 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   1106 	    {
   1107 	      child_iomsg = dtp->common.iomsg;
   1108 	      child_iomsg_len = dtp->common.iomsg_len;
   1109 	    }
   1110 	  else
   1111 	    {
   1112 	      child_iomsg = tmp_iomsg;
   1113 	      child_iomsg_len = IOMSG_LEN;
   1114 	    }
   1115 
   1116 	  /* Call the user defined unformatted READ procedure.  */
   1117 	  dtp->u.p.current_unit->child_dtio++;
   1118 	  dtp->u.p.ufdtio_ptr (dest, &unit, child_iostat, child_iomsg,
   1119 			      child_iomsg_len);
   1120 	  dtp->u.p.current_unit->child_dtio--;
   1121 	  return;
   1122     }
   1123 
   1124   if (type == BT_CHARACTER)
   1125     size *= GFC_SIZE_OF_CHAR_KIND(kind);
   1126   read_block_direct (dtp, dest, size * nelems);
   1127 
   1128   if (unlikely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_SWAP)
   1129       && kind != 1)
   1130     {
   1131       /* Handle wide chracters.  */
   1132       if (type == BT_CHARACTER)
   1133   	{
   1134   	  nelems *= size;
   1135   	  size = kind;
   1136   	}
   1137 
   1138       /* Break up complex into its constituent reals.  */
   1139       else if (type == BT_COMPLEX)
   1140   	{
   1141   	  nelems *= 2;
   1142   	  size /= 2;
   1143   	}
   1144       bswap_array (dest, dest, size, nelems);
   1145     }
   1146 }
   1147 
   1148 
   1149 /* Master function for unformatted writes.  NOTE: For kind=10 the size is 16
   1150    bytes on 64 bit machines.  The unused bytes are not initialized and never
   1151    used, which can show an error with memory checking analyzers like
   1152    valgrind.  We us BT_CLASS to denote a User Defined I/O call.  */
   1153 
   1154 static void
   1155 unformatted_write (st_parameter_dt *dtp, bt type,
   1156 		   void *source, int kind, size_t size, size_t nelems)
   1157 {
   1158   if (type == BT_CLASS)
   1159     {
   1160 	  int unit = dtp->u.p.current_unit->unit_number;
   1161 	  char tmp_iomsg[IOMSG_LEN] = "";
   1162 	  char *child_iomsg;
   1163 	  gfc_charlen_type child_iomsg_len;
   1164 	  int noiostat;
   1165 	  int *child_iostat = NULL;
   1166 
   1167 	  /* Set iostat, intent(out).  */
   1168 	  noiostat = 0;
   1169 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   1170 			  dtp->common.iostat : &noiostat;
   1171 
   1172 	  /* Set iomsg, intent(inout).  */
   1173 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   1174 	    {
   1175 	      child_iomsg = dtp->common.iomsg;
   1176 	      child_iomsg_len = dtp->common.iomsg_len;
   1177 	    }
   1178 	  else
   1179 	    {
   1180 	      child_iomsg = tmp_iomsg;
   1181 	      child_iomsg_len = IOMSG_LEN;
   1182 	    }
   1183 
   1184 	  /* Call the user defined unformatted WRITE procedure.  */
   1185 	  dtp->u.p.current_unit->child_dtio++;
   1186 	  dtp->u.p.ufdtio_ptr (source, &unit, child_iostat, child_iomsg,
   1187 			      child_iomsg_len);
   1188 	  dtp->u.p.current_unit->child_dtio--;
   1189 	  return;
   1190     }
   1191 
   1192   if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
   1193       || kind == 1)
   1194     {
   1195       size_t stride = type == BT_CHARACTER ?
   1196 		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
   1197 
   1198       write_buf (dtp, source, stride * nelems);
   1199     }
   1200   else
   1201     {
   1202 #define BSWAP_BUFSZ 512
   1203       char buffer[BSWAP_BUFSZ];
   1204       char *p;
   1205       size_t nrem;
   1206 
   1207       p = source;
   1208 
   1209       /* Handle wide chracters.  */
   1210       if (type == BT_CHARACTER && kind != 1)
   1211 	{
   1212 	  nelems *= size;
   1213 	  size = kind;
   1214 	}
   1215 
   1216       /* Break up complex into its constituent reals.  */
   1217       if (type == BT_COMPLEX)
   1218 	{
   1219 	  nelems *= 2;
   1220 	  size /= 2;
   1221 	}
   1222 
   1223       /* By now, all complex variables have been split into their
   1224 	 constituent reals.  */
   1225 
   1226       nrem = nelems;
   1227       do
   1228 	{
   1229 	  size_t nc;
   1230 	  if (size * nrem > BSWAP_BUFSZ)
   1231 	    nc = BSWAP_BUFSZ / size;
   1232 	  else
   1233 	    nc = nrem;
   1234 
   1235 	  bswap_array (buffer, p, size, nc);
   1236 	  write_buf (dtp, buffer, size * nc);
   1237 	  p += size * nc;
   1238 	  nrem -= nc;
   1239 	}
   1240       while (nrem > 0);
   1241     }
   1242 }
   1243 
   1244 
   1245 /* Return a pointer to the name of a type.  */
   1246 
   1247 const char *
   1248 type_name (bt type)
   1249 {
   1250   const char *p;
   1251 
   1252   switch (type)
   1253     {
   1254     case BT_INTEGER:
   1255       p = "INTEGER";
   1256       break;
   1257     case BT_LOGICAL:
   1258       p = "LOGICAL";
   1259       break;
   1260     case BT_CHARACTER:
   1261       p = "CHARACTER";
   1262       break;
   1263     case BT_REAL:
   1264       p = "REAL";
   1265       break;
   1266     case BT_COMPLEX:
   1267       p = "COMPLEX";
   1268       break;
   1269     case BT_CLASS:
   1270       p = "CLASS or DERIVED";
   1271       break;
   1272     default:
   1273       internal_error (NULL, "type_name(): Bad type");
   1274     }
   1275 
   1276   return p;
   1277 }
   1278 
   1279 
   1280 /* Write a constant string to the output.
   1281    This is complicated because the string can have doubled delimiters
   1282    in it.  The length in the format node is the true length.  */
   1283 
   1284 static void
   1285 write_constant_string (st_parameter_dt *dtp, const fnode *f)
   1286 {
   1287   char c, delimiter, *p, *q;
   1288   int length;
   1289 
   1290   length = f->u.string.length;
   1291   if (length == 0)
   1292     return;
   1293 
   1294   p = write_block (dtp, length);
   1295   if (p == NULL)
   1296     return;
   1297 
   1298   q = f->u.string.p;
   1299   delimiter = q[-1];
   1300 
   1301   for (; length > 0; length--)
   1302     {
   1303       c = *p++ = *q++;
   1304       if (c == delimiter && c != 'H' && c != 'h')
   1305 	q++;			/* Skip the doubled delimiter.  */
   1306     }
   1307 }
   1308 
   1309 
   1310 /* Given actual and expected types in a formatted data transfer, make
   1311    sure they agree.  If not, an error message is generated.  Returns
   1312    nonzero if something went wrong.  */
   1313 
   1314 static int
   1315 require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
   1316 {
   1317 #define BUFLEN 100
   1318   char buffer[BUFLEN];
   1319 
   1320   if (actual == expected)
   1321     return 0;
   1322 
   1323   /* Adjust item_count before emitting error message.  */
   1324   snprintf (buffer, BUFLEN,
   1325 	    "Expected %s for item %d in formatted transfer, got %s",
   1326 	   type_name (expected), dtp->u.p.item_count - 1, type_name (actual));
   1327 
   1328   format_error (dtp, f, buffer);
   1329   return 1;
   1330 }
   1331 
   1332 
   1333 /* Check that the dtio procedure required for formatted IO is present.  */
   1334 
   1335 static int
   1336 check_dtio_proc (st_parameter_dt *dtp, const fnode *f)
   1337 {
   1338   char buffer[BUFLEN];
   1339 
   1340   if (dtp->u.p.fdtio_ptr != NULL)
   1341     return 0;
   1342 
   1343   snprintf (buffer, BUFLEN,
   1344 	    "Missing DTIO procedure or intrinsic type passed for item %d "
   1345 	    "in formatted transfer",
   1346 	    dtp->u.p.item_count - 1);
   1347 
   1348   format_error (dtp, f, buffer);
   1349   return 1;
   1350 }
   1351 
   1352 
   1353 static int
   1354 require_numeric_type (st_parameter_dt *dtp, bt actual, const fnode *f)
   1355 {
   1356 #define BUFLEN 100
   1357   char buffer[BUFLEN];
   1358 
   1359   if (actual == BT_INTEGER || actual == BT_REAL || actual == BT_COMPLEX)
   1360     return 0;
   1361 
   1362   /* Adjust item_count before emitting error message.  */
   1363   snprintf (buffer, BUFLEN,
   1364 	    "Expected numeric type for item %d in formatted transfer, got %s",
   1365 	    dtp->u.p.item_count - 1, type_name (actual));
   1366 
   1367   format_error (dtp, f, buffer);
   1368   return 1;
   1369 }
   1370 
   1371 static char *
   1372 get_dt_format (char *p, gfc_charlen_type *length)
   1373 {
   1374   char delim = p[-1];  /* The delimiter is always the first character back.  */
   1375   char c, *q, *res;
   1376   gfc_charlen_type len = *length; /* This length already correct, less 'DT'.  */
   1377 
   1378   res = q = xmalloc (len + 2);
   1379 
   1380   /* Set the beginning of the string to 'DT', length adjusted below.  */
   1381   *q++ = 'D';
   1382   *q++ = 'T';
   1383 
   1384   /* The string may contain doubled quotes so scan and skip as needed.  */
   1385   for (; len > 0; len--)
   1386     {
   1387       c = *q++ = *p++;
   1388       if (c == delim)
   1389 	p++;  /* Skip the doubled delimiter.  */
   1390     }
   1391 
   1392   /* Adjust the string length by two now that we are done.  */
   1393   *length += 2;
   1394 
   1395   return res;
   1396 }
   1397 
   1398 
   1399 /* This function is in the main loop for a formatted data transfer
   1400    statement.  It would be natural to implement this as a coroutine
   1401    with the user program, but C makes that awkward.  We loop,
   1402    processing format elements.  When we actually have to transfer
   1403    data instead of just setting flags, we return control to the user
   1404    program which calls a function that supplies the address and type
   1405    of the next element, then comes back here to process it.  */
   1406 
   1407 static void
   1408 formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind,
   1409 				size_t size)
   1410 {
   1411   int pos, bytes_used;
   1412   const fnode *f;
   1413   format_token t;
   1414   int n;
   1415   int consume_data_flag;
   1416 
   1417   /* Change a complex data item into a pair of reals.  */
   1418 
   1419   n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
   1420   if (type == BT_COMPLEX)
   1421     {
   1422       type = BT_REAL;
   1423       size /= 2;
   1424     }
   1425 
   1426   /* If there's an EOR condition, we simulate finalizing the transfer
   1427      by doing nothing.  */
   1428   if (dtp->u.p.eor_condition)
   1429     return;
   1430 
   1431   /* Set this flag so that commas in reads cause the read to complete before
   1432      the entire field has been read.  The next read field will start right after
   1433      the comma in the stream.  (Set to 0 for character reads).  */
   1434   dtp->u.p.sf_read_comma =
   1435     dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
   1436 
   1437   for (;;)
   1438     {
   1439       /* If reversion has occurred and there is another real data item,
   1440 	 then we have to move to the next record.  */
   1441       if (dtp->u.p.reversion_flag && n > 0)
   1442 	{
   1443 	  dtp->u.p.reversion_flag = 0;
   1444 	  next_record (dtp, 0);
   1445 	}
   1446 
   1447       consume_data_flag = 1;
   1448       if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   1449 	break;
   1450 
   1451       f = next_format (dtp);
   1452       if (f == NULL)
   1453 	{
   1454 	  /* No data descriptors left.  */
   1455 	  if (unlikely (n > 0))
   1456 	    generate_error (&dtp->common, LIBERROR_FORMAT,
   1457 		"Insufficient data descriptors in format after reversion");
   1458 	  return;
   1459 	}
   1460 
   1461       t = f->format;
   1462 
   1463       bytes_used = (int)(dtp->u.p.current_unit->recl
   1464 		   - dtp->u.p.current_unit->bytes_left);
   1465 
   1466       if (is_stream_io(dtp))
   1467 	bytes_used = 0;
   1468 
   1469       switch (t)
   1470 	{
   1471 	case FMT_I:
   1472 	  if (n == 0)
   1473 	    goto need_read_data;
   1474 	  if (require_type (dtp, BT_INTEGER, type, f))
   1475 	    return;
   1476 	  read_decimal (dtp, f, p, kind);
   1477 	  break;
   1478 
   1479 	case FMT_B:
   1480 	  if (n == 0)
   1481 	    goto need_read_data;
   1482 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1483 	      && require_numeric_type (dtp, type, f))
   1484 	    return;
   1485 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1486               && require_type (dtp, BT_INTEGER, type, f))
   1487 	    return;
   1488 	  read_radix (dtp, f, p, kind, 2);
   1489 	  break;
   1490 
   1491 	case FMT_O:
   1492 	  if (n == 0)
   1493 	    goto need_read_data;
   1494 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1495 	      && require_numeric_type (dtp, type, f))
   1496 	    return;
   1497 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1498               && require_type (dtp, BT_INTEGER, type, f))
   1499 	    return;
   1500 	  read_radix (dtp, f, p, kind, 8);
   1501 	  break;
   1502 
   1503 	case FMT_Z:
   1504 	  if (n == 0)
   1505 	    goto need_read_data;
   1506 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1507 	      && require_numeric_type (dtp, type, f))
   1508 	    return;
   1509 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1510               && require_type (dtp, BT_INTEGER, type, f))
   1511 	    return;
   1512 	  read_radix (dtp, f, p, kind, 16);
   1513 	  break;
   1514 
   1515 	case FMT_A:
   1516 	  if (n == 0)
   1517 	    goto need_read_data;
   1518 
   1519 	  /* It is possible to have FMT_A with something not BT_CHARACTER such
   1520 	     as when writing out hollerith strings, so check both type
   1521 	     and kind before calling wide character routines.  */
   1522 	  if (type == BT_CHARACTER && kind == 4)
   1523 	    read_a_char4 (dtp, f, p, size);
   1524 	  else
   1525 	    read_a (dtp, f, p, size);
   1526 	  break;
   1527 
   1528 	case FMT_L:
   1529 	  if (n == 0)
   1530 	    goto need_read_data;
   1531 	  read_l (dtp, f, p, kind);
   1532 	  break;
   1533 
   1534 	case FMT_D:
   1535 	  if (n == 0)
   1536 	    goto need_read_data;
   1537 	  if (require_type (dtp, BT_REAL, type, f))
   1538 	    return;
   1539 	  read_f (dtp, f, p, kind);
   1540 	  break;
   1541 
   1542 	case FMT_DT:
   1543 	  if (n == 0)
   1544 	    goto need_read_data;
   1545 
   1546 	  if (check_dtio_proc (dtp, f))
   1547 	    return;
   1548 	  if (require_type (dtp, BT_CLASS, type, f))
   1549 	    return;
   1550 	  int unit = dtp->u.p.current_unit->unit_number;
   1551 	  char dt[] = "DT";
   1552 	  char tmp_iomsg[IOMSG_LEN] = "";
   1553 	  char *child_iomsg;
   1554 	  gfc_charlen_type child_iomsg_len;
   1555 	  int noiostat;
   1556 	  int *child_iostat = NULL;
   1557 	  char *iotype;
   1558 	  gfc_charlen_type iotype_len = f->u.udf.string_len;
   1559 
   1560 	  /* Build the iotype string.  */
   1561 	  if (iotype_len == 0)
   1562 	    {
   1563 	      iotype_len = 2;
   1564 	      iotype = dt;
   1565 	    }
   1566 	  else
   1567 	    iotype = get_dt_format (f->u.udf.string, &iotype_len);
   1568 
   1569 	  /* Set iostat, intent(out).  */
   1570 	  noiostat = 0;
   1571 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   1572 			  dtp->common.iostat : &noiostat;
   1573 
   1574 	  /* Set iomsg, intent(inout).  */
   1575 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   1576 	    {
   1577 	      child_iomsg = dtp->common.iomsg;
   1578 	      child_iomsg_len = dtp->common.iomsg_len;
   1579 	    }
   1580 	  else
   1581 	    {
   1582 	      child_iomsg = tmp_iomsg;
   1583 	      child_iomsg_len = IOMSG_LEN;
   1584 	    }
   1585 
   1586 	  /* Call the user defined formatted READ procedure.  */
   1587 	  dtp->u.p.current_unit->child_dtio++;
   1588 	  dtp->u.p.current_unit->last_char = EOF - 1;
   1589 	  dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
   1590 			      child_iostat, child_iomsg,
   1591 			      iotype_len, child_iomsg_len);
   1592 	  dtp->u.p.current_unit->child_dtio--;
   1593 
   1594 	  if (f->u.udf.string_len != 0)
   1595 	    free (iotype);
   1596 	  /* Note: vlist is freed in free_format_data.  */
   1597 	  break;
   1598 
   1599 	case FMT_E:
   1600 	  if (n == 0)
   1601 	    goto need_read_data;
   1602 	  if (require_type (dtp, BT_REAL, type, f))
   1603 	    return;
   1604 	  read_f (dtp, f, p, kind);
   1605 	  break;
   1606 
   1607 	case FMT_EN:
   1608 	  if (n == 0)
   1609 	    goto need_read_data;
   1610 	  if (require_type (dtp, BT_REAL, type, f))
   1611 	    return;
   1612 	  read_f (dtp, f, p, kind);
   1613 	  break;
   1614 
   1615 	case FMT_ES:
   1616 	  if (n == 0)
   1617 	    goto need_read_data;
   1618 	  if (require_type (dtp, BT_REAL, type, f))
   1619 	    return;
   1620 	  read_f (dtp, f, p, kind);
   1621 	  break;
   1622 
   1623 	case FMT_F:
   1624 	  if (n == 0)
   1625 	    goto need_read_data;
   1626 	  if (require_type (dtp, BT_REAL, type, f))
   1627 	    return;
   1628 	  read_f (dtp, f, p, kind);
   1629 	  break;
   1630 
   1631 	case FMT_G:
   1632 	  if (n == 0)
   1633 	    goto need_read_data;
   1634 	  switch (type)
   1635 	    {
   1636 	      case BT_INTEGER:
   1637 		read_decimal (dtp, f, p, kind);
   1638 		break;
   1639 	      case BT_LOGICAL:
   1640 		read_l (dtp, f, p, kind);
   1641 		break;
   1642 	      case BT_CHARACTER:
   1643 		if (kind == 4)
   1644 		  read_a_char4 (dtp, f, p, size);
   1645 		else
   1646 		  read_a (dtp, f, p, size);
   1647 		break;
   1648 	      case BT_REAL:
   1649 		read_f (dtp, f, p, kind);
   1650 		break;
   1651 	      default:
   1652 		internal_error (&dtp->common,
   1653 				"formatted_transfer (): Bad type");
   1654 	    }
   1655 	  break;
   1656 
   1657 	case FMT_STRING:
   1658 	  consume_data_flag = 0;
   1659 	  format_error (dtp, f, "Constant string in input format");
   1660 	  return;
   1661 
   1662 	/* Format codes that don't transfer data.  */
   1663 	case FMT_X:
   1664 	case FMT_TR:
   1665 	  consume_data_flag = 0;
   1666 	  dtp->u.p.skips += f->u.n;
   1667 	  pos = bytes_used + dtp->u.p.skips - 1;
   1668 	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
   1669 	  read_x (dtp, f->u.n);
   1670 	  break;
   1671 
   1672 	case FMT_TL:
   1673 	case FMT_T:
   1674 	  consume_data_flag = 0;
   1675 
   1676 	  if (f->format == FMT_TL)
   1677 	    {
   1678 	      /* Handle the special case when no bytes have been used yet.
   1679 	         Cannot go below zero. */
   1680 	      if (bytes_used == 0)
   1681 		{
   1682 		  dtp->u.p.pending_spaces -= f->u.n;
   1683 		  dtp->u.p.skips -= f->u.n;
   1684 		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
   1685 		}
   1686 
   1687 	      pos = bytes_used - f->u.n;
   1688 	    }
   1689 	  else /* FMT_T */
   1690 	    pos = f->u.n - 1;
   1691 
   1692 	  /* Standard 10.6.1.1: excessive left tabbing is reset to the
   1693 	     left tab limit.  We do not check if the position has gone
   1694 	     beyond the end of record because a subsequent tab could
   1695 	     bring us back again.  */
   1696 	  pos = pos < 0 ? 0 : pos;
   1697 
   1698 	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
   1699 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
   1700 				    + pos - dtp->u.p.max_pos;
   1701 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
   1702 				    ? 0 : dtp->u.p.pending_spaces;
   1703 	  if (dtp->u.p.skips == 0)
   1704 	    break;
   1705 
   1706 	  /* Adjust everything for end-of-record condition */
   1707 	  if (dtp->u.p.sf_seen_eor && !is_internal_unit (dtp))
   1708 	    {
   1709               dtp->u.p.current_unit->bytes_left -= dtp->u.p.sf_seen_eor;
   1710               dtp->u.p.skips -= dtp->u.p.sf_seen_eor;
   1711 	      bytes_used = pos;
   1712 	      if (dtp->u.p.pending_spaces == 0)
   1713 		dtp->u.p.sf_seen_eor = 0;
   1714 	    }
   1715 	  if (dtp->u.p.skips < 0)
   1716 	    {
   1717               if (is_internal_unit (dtp))
   1718                 sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
   1719               else
   1720                 fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
   1721 	      dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
   1722 	      dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   1723 	    }
   1724 	  else
   1725 	    read_x (dtp, dtp->u.p.skips);
   1726 	  break;
   1727 
   1728 	case FMT_S:
   1729 	  consume_data_flag = 0;
   1730 	  dtp->u.p.sign_status = SIGN_S;
   1731 	  break;
   1732 
   1733 	case FMT_SS:
   1734 	  consume_data_flag = 0;
   1735 	  dtp->u.p.sign_status = SIGN_SS;
   1736 	  break;
   1737 
   1738 	case FMT_SP:
   1739 	  consume_data_flag = 0;
   1740 	  dtp->u.p.sign_status = SIGN_SP;
   1741 	  break;
   1742 
   1743 	case FMT_BN:
   1744 	  consume_data_flag = 0 ;
   1745 	  dtp->u.p.blank_status = BLANK_NULL;
   1746 	  break;
   1747 
   1748 	case FMT_BZ:
   1749 	  consume_data_flag = 0;
   1750 	  dtp->u.p.blank_status = BLANK_ZERO;
   1751 	  break;
   1752 
   1753 	case FMT_DC:
   1754 	  consume_data_flag = 0;
   1755 	  dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
   1756 	  break;
   1757 
   1758 	case FMT_DP:
   1759 	  consume_data_flag = 0;
   1760 	  dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
   1761 	  break;
   1762 
   1763 	case FMT_RC:
   1764 	  consume_data_flag = 0;
   1765 	  dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
   1766 	  break;
   1767 
   1768 	case FMT_RD:
   1769 	  consume_data_flag = 0;
   1770 	  dtp->u.p.current_unit->round_status = ROUND_DOWN;
   1771 	  break;
   1772 
   1773 	case FMT_RN:
   1774 	  consume_data_flag = 0;
   1775 	  dtp->u.p.current_unit->round_status = ROUND_NEAREST;
   1776 	  break;
   1777 
   1778 	case FMT_RP:
   1779 	  consume_data_flag = 0;
   1780 	  dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
   1781 	  break;
   1782 
   1783 	case FMT_RU:
   1784 	  consume_data_flag = 0;
   1785 	  dtp->u.p.current_unit->round_status = ROUND_UP;
   1786 	  break;
   1787 
   1788 	case FMT_RZ:
   1789 	  consume_data_flag = 0;
   1790 	  dtp->u.p.current_unit->round_status = ROUND_ZERO;
   1791 	  break;
   1792 
   1793 	case FMT_P:
   1794 	  consume_data_flag = 0;
   1795 	  dtp->u.p.scale_factor = f->u.k;
   1796 	  break;
   1797 
   1798 	case FMT_DOLLAR:
   1799 	  consume_data_flag = 0;
   1800 	  dtp->u.p.seen_dollar = 1;
   1801 	  break;
   1802 
   1803 	case FMT_SLASH:
   1804 	  consume_data_flag = 0;
   1805 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   1806 	  next_record (dtp, 0);
   1807 	  break;
   1808 
   1809 	case FMT_COLON:
   1810 	  /* A colon descriptor causes us to exit this loop (in
   1811 	     particular preventing another / descriptor from being
   1812 	     processed) unless there is another data item to be
   1813 	     transferred.  */
   1814 	  consume_data_flag = 0;
   1815 	  if (n == 0)
   1816 	    return;
   1817 	  break;
   1818 
   1819 	default:
   1820 	  internal_error (&dtp->common, "Bad format node");
   1821 	}
   1822 
   1823       /* Adjust the item count and data pointer.  */
   1824 
   1825       if ((consume_data_flag > 0) && (n > 0))
   1826 	{
   1827 	  n--;
   1828 	  p = ((char *) p) + size;
   1829 	}
   1830 
   1831       dtp->u.p.skips = 0;
   1832 
   1833       pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
   1834       dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
   1835     }
   1836 
   1837   return;
   1838 
   1839   /* Come here when we need a data descriptor but don't have one.  We
   1840      push the current format node back onto the input, then return and
   1841      let the user program call us back with the data.  */
   1842  need_read_data:
   1843   unget_format (dtp, f);
   1844 }
   1845 
   1846 
   1847 static void
   1848 formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind,
   1849 				 size_t size)
   1850 {
   1851   gfc_offset pos, bytes_used;
   1852   const fnode *f;
   1853   format_token t;
   1854   int n;
   1855   int consume_data_flag;
   1856 
   1857   /* Change a complex data item into a pair of reals.  */
   1858 
   1859   n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
   1860   if (type == BT_COMPLEX)
   1861     {
   1862       type = BT_REAL;
   1863       size /= 2;
   1864     }
   1865 
   1866   /* If there's an EOR condition, we simulate finalizing the transfer
   1867      by doing nothing.  */
   1868   if (dtp->u.p.eor_condition)
   1869     return;
   1870 
   1871   /* Set this flag so that commas in reads cause the read to complete before
   1872      the entire field has been read.  The next read field will start right after
   1873      the comma in the stream.  (Set to 0 for character reads).  */
   1874   dtp->u.p.sf_read_comma =
   1875     dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
   1876 
   1877   for (;;)
   1878     {
   1879       /* If reversion has occurred and there is another real data item,
   1880 	 then we have to move to the next record.  */
   1881       if (dtp->u.p.reversion_flag && n > 0)
   1882 	{
   1883 	  dtp->u.p.reversion_flag = 0;
   1884 	  next_record (dtp, 0);
   1885 	}
   1886 
   1887       consume_data_flag = 1;
   1888       if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   1889 	break;
   1890 
   1891       f = next_format (dtp);
   1892       if (f == NULL)
   1893 	{
   1894 	  /* No data descriptors left.  */
   1895 	  if (unlikely (n > 0))
   1896 	    generate_error (&dtp->common, LIBERROR_FORMAT,
   1897 		"Insufficient data descriptors in format after reversion");
   1898 	  return;
   1899 	}
   1900 
   1901       /* Now discharge T, TR and X movements to the right.  This is delayed
   1902 	 until a data producing format to suppress trailing spaces.  */
   1903 
   1904       t = f->format;
   1905       if (dtp->u.p.mode == WRITING && dtp->u.p.skips != 0
   1906 	&& ((n>0 && (  t == FMT_I  || t == FMT_B  || t == FMT_O
   1907 		    || t == FMT_Z  || t == FMT_F  || t == FMT_E
   1908 		    || t == FMT_EN || t == FMT_ES || t == FMT_G
   1909 		    || t == FMT_L  || t == FMT_A  || t == FMT_D
   1910 		    || t == FMT_DT))
   1911 	    || t == FMT_STRING))
   1912 	{
   1913 	  if (dtp->u.p.skips > 0)
   1914 	    {
   1915 	      gfc_offset tmp;
   1916 	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
   1917 	      tmp = dtp->u.p.current_unit->recl
   1918 			  - dtp->u.p.current_unit->bytes_left;
   1919 	      dtp->u.p.max_pos =
   1920 		dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
   1921 	      dtp->u.p.skips = 0;
   1922 	    }
   1923 	  if (dtp->u.p.skips < 0)
   1924 	    {
   1925               if (is_internal_unit (dtp))
   1926 	        sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
   1927               else
   1928                 fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
   1929 	      dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
   1930 	    }
   1931 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   1932 	}
   1933 
   1934       bytes_used = dtp->u.p.current_unit->recl
   1935 		   - dtp->u.p.current_unit->bytes_left;
   1936 
   1937       if (is_stream_io(dtp))
   1938 	bytes_used = 0;
   1939 
   1940       switch (t)
   1941 	{
   1942 	case FMT_I:
   1943 	  if (n == 0)
   1944 	    goto need_data;
   1945 	  if (require_type (dtp, BT_INTEGER, type, f))
   1946 	    return;
   1947 	  write_i (dtp, f, p, kind);
   1948 	  break;
   1949 
   1950 	case FMT_B:
   1951 	  if (n == 0)
   1952 	    goto need_data;
   1953 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1954 	      && require_numeric_type (dtp, type, f))
   1955 	    return;
   1956 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1957               && require_type (dtp, BT_INTEGER, type, f))
   1958 	    return;
   1959 	  write_b (dtp, f, p, kind);
   1960 	  break;
   1961 
   1962 	case FMT_O:
   1963 	  if (n == 0)
   1964 	    goto need_data;
   1965 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1966 	      && require_numeric_type (dtp, type, f))
   1967 	    return;
   1968 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1969               && require_type (dtp, BT_INTEGER, type, f))
   1970 	    return;
   1971 	  write_o (dtp, f, p, kind);
   1972 	  break;
   1973 
   1974 	case FMT_Z:
   1975 	  if (n == 0)
   1976 	    goto need_data;
   1977 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1978 	      && require_numeric_type (dtp, type, f))
   1979 	    return;
   1980 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1981               && require_type (dtp, BT_INTEGER, type, f))
   1982 	    return;
   1983 	  write_z (dtp, f, p, kind);
   1984 	  break;
   1985 
   1986 	case FMT_A:
   1987 	  if (n == 0)
   1988 	    goto need_data;
   1989 
   1990 	  /* It is possible to have FMT_A with something not BT_CHARACTER such
   1991 	     as when writing out hollerith strings, so check both type
   1992 	     and kind before calling wide character routines.  */
   1993 	  if (type == BT_CHARACTER && kind == 4)
   1994 	    write_a_char4 (dtp, f, p, size);
   1995 	  else
   1996 	    write_a (dtp, f, p, size);
   1997 	  break;
   1998 
   1999 	case FMT_L:
   2000 	  if (n == 0)
   2001 	    goto need_data;
   2002 	  write_l (dtp, f, p, kind);
   2003 	  break;
   2004 
   2005 	case FMT_D:
   2006 	  if (n == 0)
   2007 	    goto need_data;
   2008 	  if (require_type (dtp, BT_REAL, type, f))
   2009 	    return;
   2010 	  write_d (dtp, f, p, kind);
   2011 	  break;
   2012 
   2013 	case FMT_DT:
   2014 	  if (n == 0)
   2015 	    goto need_data;
   2016 	  int unit = dtp->u.p.current_unit->unit_number;
   2017 	  char dt[] = "DT";
   2018 	  char tmp_iomsg[IOMSG_LEN] = "";
   2019 	  char *child_iomsg;
   2020 	  gfc_charlen_type child_iomsg_len;
   2021 	  int noiostat;
   2022 	  int *child_iostat = NULL;
   2023 	  char *iotype;
   2024 	  gfc_charlen_type iotype_len = f->u.udf.string_len;
   2025 
   2026 	  /* Build the iotype string.  */
   2027 	  if (iotype_len == 0)
   2028 	    {
   2029 	      iotype_len = 2;
   2030 	      iotype = dt;
   2031 	    }
   2032 	  else
   2033 	    iotype = get_dt_format (f->u.udf.string, &iotype_len);
   2034 
   2035 	  /* Set iostat, intent(out).  */
   2036 	  noiostat = 0;
   2037 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   2038 			  dtp->common.iostat : &noiostat;
   2039 
   2040 	  /* Set iomsg, intent(inout).  */
   2041 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   2042 	    {
   2043 	      child_iomsg = dtp->common.iomsg;
   2044 	      child_iomsg_len = dtp->common.iomsg_len;
   2045 	    }
   2046 	  else
   2047 	    {
   2048 	      child_iomsg = tmp_iomsg;
   2049 	      child_iomsg_len = IOMSG_LEN;
   2050 	    }
   2051 
   2052 	  if (check_dtio_proc (dtp, f))
   2053 	    return;
   2054 
   2055 	  /* Call the user defined formatted WRITE procedure.  */
   2056 	  dtp->u.p.current_unit->child_dtio++;
   2057 
   2058 	  dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
   2059 			      child_iostat, child_iomsg,
   2060 			      iotype_len, child_iomsg_len);
   2061 	  dtp->u.p.current_unit->child_dtio--;
   2062 
   2063 	  if (f->u.udf.string_len != 0)
   2064 	    free (iotype);
   2065 	  /* Note: vlist is freed in free_format_data.  */
   2066 	  break;
   2067 
   2068 	case FMT_E:
   2069 	  if (n == 0)
   2070 	    goto need_data;
   2071 	  if (require_type (dtp, BT_REAL, type, f))
   2072 	    return;
   2073 	  write_e (dtp, f, p, kind);
   2074 	  break;
   2075 
   2076 	case FMT_EN:
   2077 	  if (n == 0)
   2078 	    goto need_data;
   2079 	  if (require_type (dtp, BT_REAL, type, f))
   2080 	    return;
   2081 	  write_en (dtp, f, p, kind);
   2082 	  break;
   2083 
   2084 	case FMT_ES:
   2085 	  if (n == 0)
   2086 	    goto need_data;
   2087 	  if (require_type (dtp, BT_REAL, type, f))
   2088 	    return;
   2089 	  write_es (dtp, f, p, kind);
   2090 	  break;
   2091 
   2092 	case FMT_F:
   2093 	  if (n == 0)
   2094 	    goto need_data;
   2095 	  if (require_type (dtp, BT_REAL, type, f))
   2096 	    return;
   2097 	  write_f (dtp, f, p, kind);
   2098 	  break;
   2099 
   2100 	case FMT_G:
   2101 	  if (n == 0)
   2102 	    goto need_data;
   2103 	  switch (type)
   2104 	    {
   2105 	      case BT_INTEGER:
   2106 		write_i (dtp, f, p, kind);
   2107 		break;
   2108 	      case BT_LOGICAL:
   2109 		write_l (dtp, f, p, kind);
   2110 		break;
   2111 	      case BT_CHARACTER:
   2112 		if (kind == 4)
   2113 		  write_a_char4 (dtp, f, p, size);
   2114 		else
   2115 		  write_a (dtp, f, p, size);
   2116 		break;
   2117 	      case BT_REAL:
   2118 		if (f->u.real.w == 0)
   2119                   write_real_g0 (dtp, p, kind, f->u.real.d);
   2120 		else
   2121 		  write_d (dtp, f, p, kind);
   2122 		break;
   2123 	      default:
   2124 		internal_error (&dtp->common,
   2125 				"formatted_transfer (): Bad type");
   2126 	    }
   2127 	  break;
   2128 
   2129 	case FMT_STRING:
   2130 	  consume_data_flag = 0;
   2131 	  write_constant_string (dtp, f);
   2132 	  break;
   2133 
   2134 	/* Format codes that don't transfer data.  */
   2135 	case FMT_X:
   2136 	case FMT_TR:
   2137 	  consume_data_flag = 0;
   2138 
   2139 	  dtp->u.p.skips += f->u.n;
   2140 	  pos = bytes_used + dtp->u.p.skips - 1;
   2141 	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
   2142 	  /* Writes occur just before the switch on f->format, above, so
   2143 	     that trailing blanks are suppressed, unless we are doing a
   2144 	     non-advancing write in which case we want to output the blanks
   2145 	     now.  */
   2146 	  if (dtp->u.p.advance_status == ADVANCE_NO)
   2147 	    {
   2148 	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
   2149 	      dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   2150 	    }
   2151 	  break;
   2152 
   2153 	case FMT_TL:
   2154 	case FMT_T:
   2155 	  consume_data_flag = 0;
   2156 
   2157 	  if (f->format == FMT_TL)
   2158 	    {
   2159 
   2160 	      /* Handle the special case when no bytes have been used yet.
   2161 	         Cannot go below zero. */
   2162 	      if (bytes_used == 0)
   2163 		{
   2164 		  dtp->u.p.pending_spaces -= f->u.n;
   2165 		  dtp->u.p.skips -= f->u.n;
   2166 		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
   2167 		}
   2168 
   2169 	      pos = bytes_used - f->u.n;
   2170 	    }
   2171 	  else /* FMT_T */
   2172 	    pos = f->u.n - dtp->u.p.pending_spaces - 1;
   2173 
   2174 	  /* Standard 10.6.1.1: excessive left tabbing is reset to the
   2175 	     left tab limit.  We do not check if the position has gone
   2176 	     beyond the end of record because a subsequent tab could
   2177 	     bring us back again.  */
   2178 	  pos = pos < 0 ? 0 : pos;
   2179 
   2180 	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
   2181 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
   2182 				    + pos - dtp->u.p.max_pos;
   2183 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
   2184 				    ? 0 : dtp->u.p.pending_spaces;
   2185 	  break;
   2186 
   2187 	case FMT_S:
   2188 	  consume_data_flag = 0;
   2189 	  dtp->u.p.sign_status = SIGN_S;
   2190 	  break;
   2191 
   2192 	case FMT_SS:
   2193 	  consume_data_flag = 0;
   2194 	  dtp->u.p.sign_status = SIGN_SS;
   2195 	  break;
   2196 
   2197 	case FMT_SP:
   2198 	  consume_data_flag = 0;
   2199 	  dtp->u.p.sign_status = SIGN_SP;
   2200 	  break;
   2201 
   2202 	case FMT_BN:
   2203 	  consume_data_flag = 0 ;
   2204 	  dtp->u.p.blank_status = BLANK_NULL;
   2205 	  break;
   2206 
   2207 	case FMT_BZ:
   2208 	  consume_data_flag = 0;
   2209 	  dtp->u.p.blank_status = BLANK_ZERO;
   2210 	  break;
   2211 
   2212 	case FMT_DC:
   2213 	  consume_data_flag = 0;
   2214 	  dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
   2215 	  break;
   2216 
   2217 	case FMT_DP:
   2218 	  consume_data_flag = 0;
   2219 	  dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
   2220 	  break;
   2221 
   2222 	case FMT_RC:
   2223 	  consume_data_flag = 0;
   2224 	  dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
   2225 	  break;
   2226 
   2227 	case FMT_RD:
   2228 	  consume_data_flag = 0;
   2229 	  dtp->u.p.current_unit->round_status = ROUND_DOWN;
   2230 	  break;
   2231 
   2232 	case FMT_RN:
   2233 	  consume_data_flag = 0;
   2234 	  dtp->u.p.current_unit->round_status = ROUND_NEAREST;
   2235 	  break;
   2236 
   2237 	case FMT_RP:
   2238 	  consume_data_flag = 0;
   2239 	  dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
   2240 	  break;
   2241 
   2242 	case FMT_RU:
   2243 	  consume_data_flag = 0;
   2244 	  dtp->u.p.current_unit->round_status = ROUND_UP;
   2245 	  break;
   2246 
   2247 	case FMT_RZ:
   2248 	  consume_data_flag = 0;
   2249 	  dtp->u.p.current_unit->round_status = ROUND_ZERO;
   2250 	  break;
   2251 
   2252 	case FMT_P:
   2253 	  consume_data_flag = 0;
   2254 	  dtp->u.p.scale_factor = f->u.k;
   2255 	  break;
   2256 
   2257 	case FMT_DOLLAR:
   2258 	  consume_data_flag = 0;
   2259 	  dtp->u.p.seen_dollar = 1;
   2260 	  break;
   2261 
   2262 	case FMT_SLASH:
   2263 	  consume_data_flag = 0;
   2264 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   2265 	  next_record (dtp, 0);
   2266 	  break;
   2267 
   2268 	case FMT_COLON:
   2269 	  /* A colon descriptor causes us to exit this loop (in
   2270 	     particular preventing another / descriptor from being
   2271 	     processed) unless there is another data item to be
   2272 	     transferred.  */
   2273 	  consume_data_flag = 0;
   2274 	  if (n == 0)
   2275 	    return;
   2276 	  break;
   2277 
   2278 	default:
   2279 	  internal_error (&dtp->common, "Bad format node");
   2280 	}
   2281 
   2282       /* Adjust the item count and data pointer.  */
   2283 
   2284       if ((consume_data_flag > 0) && (n > 0))
   2285 	{
   2286 	  n--;
   2287 	  p = ((char *) p) + size;
   2288 	}
   2289 
   2290       pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left;
   2291       dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
   2292     }
   2293 
   2294   return;
   2295 
   2296   /* Come here when we need a data descriptor but don't have one.  We
   2297      push the current format node back onto the input, then return and
   2298      let the user program call us back with the data.  */
   2299  need_data:
   2300   unget_format (dtp, f);
   2301 }
   2302 
   2303   /* This function is first called from data_init_transfer to initiate the loop
   2304      over each item in the format, transferring data as required.  Subsequent
   2305      calls to this function occur for each data item foound in the READ/WRITE
   2306      statement.  The item_count is incremented for each call.  Since the first
   2307      call is from data_transfer_init, the item_count is always one greater than
   2308      the actual count number of the item being transferred.  */
   2309 
   2310 static void
   2311 formatted_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
   2312 		    size_t size, size_t nelems)
   2313 {
   2314   size_t elem;
   2315   char *tmp;
   2316 
   2317   tmp = (char *) p;
   2318   size_t stride = type == BT_CHARACTER ?
   2319 		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
   2320   if (dtp->u.p.mode == READING)
   2321     {
   2322       /* Big loop over all the elements.  */
   2323       for (elem = 0; elem < nelems; elem++)
   2324 	{
   2325 	  dtp->u.p.item_count++;
   2326 	  formatted_transfer_scalar_read (dtp, type, tmp + stride*elem, kind, size);
   2327 	}
   2328     }
   2329   else
   2330     {
   2331       /* Big loop over all the elements.  */
   2332       for (elem = 0; elem < nelems; elem++)
   2333 	{
   2334 	  dtp->u.p.item_count++;
   2335 	  formatted_transfer_scalar_write (dtp, type, tmp + stride*elem, kind, size);
   2336 	}
   2337     }
   2338 }
   2339 
   2340 /* Wrapper function for I/O of scalar types.  If this should be an async I/O
   2341    request, queue it.  For a synchronous write on an async unit, perform the
   2342    wait operation and return an error.  For all synchronous writes, call the
   2343    right transfer function.  */
   2344 
   2345 static void
   2346 wrap_scalar_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
   2347 		      size_t size, size_t n_elem)
   2348 {
   2349   if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
   2350     {
   2351       if (dtp->u.p.async)
   2352 	{
   2353 	  transfer_args args;
   2354 	  args.scalar.transfer = dtp->u.p.transfer;
   2355 	  args.scalar.arg_bt = type;
   2356 	  args.scalar.data = p;
   2357 	  args.scalar.i = kind;
   2358 	  args.scalar.s1 = size;
   2359 	  args.scalar.s2 = n_elem;
   2360 	  enqueue_transfer (dtp->u.p.current_unit->au, &args,
   2361 			    AIO_TRANSFER_SCALAR);
   2362 	  return;
   2363 	}
   2364     }
   2365   /* Come here if there was no asynchronous I/O to be scheduled.  */
   2366   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2367     return;
   2368 
   2369   dtp->u.p.transfer (dtp, type, p, kind, size, 1);
   2370 }
   2371 
   2372 
   2373 /* Data transfer entry points.  The type of the data entity is
   2374    implicit in the subroutine call.  This prevents us from having to
   2375    share a common enum with the compiler.  */
   2376 
   2377 void
   2378 transfer_integer (st_parameter_dt *dtp, void *p, int kind)
   2379 {
   2380     wrap_scalar_transfer (dtp, BT_INTEGER, p, kind, kind, 1);
   2381 }
   2382 
   2383 void
   2384 transfer_integer_write (st_parameter_dt *dtp, void *p, int kind)
   2385 {
   2386   transfer_integer (dtp, p, kind);
   2387 }
   2388 
   2389 void
   2390 transfer_real (st_parameter_dt *dtp, void *p, int kind)
   2391 {
   2392   size_t size;
   2393   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2394     return;
   2395   size = size_from_real_kind (kind);
   2396   wrap_scalar_transfer (dtp, BT_REAL, p, kind, size, 1);
   2397 }
   2398 
   2399 void
   2400 transfer_real_write (st_parameter_dt *dtp, void *p, int kind)
   2401 {
   2402   transfer_real (dtp, p, kind);
   2403 }
   2404 
   2405 void
   2406 transfer_logical (st_parameter_dt *dtp, void *p, int kind)
   2407 {
   2408   wrap_scalar_transfer (dtp, BT_LOGICAL, p, kind, kind, 1);
   2409 }
   2410 
   2411 void
   2412 transfer_logical_write (st_parameter_dt *dtp, void *p, int kind)
   2413 {
   2414   transfer_logical (dtp, p, kind);
   2415 }
   2416 
   2417 void
   2418 transfer_character (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
   2419 {
   2420   static char *empty_string[0];
   2421 
   2422   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2423     return;
   2424 
   2425   /* Strings of zero length can have p == NULL, which confuses the
   2426      transfer routines into thinking we need more data elements.  To avoid
   2427      this, we give them a nice pointer.  */
   2428   if (len == 0 && p == NULL)
   2429     p = empty_string;
   2430 
   2431   /* Set kind here to 1.  */
   2432   wrap_scalar_transfer (dtp, BT_CHARACTER, p, 1, len, 1);
   2433 }
   2434 
   2435 void
   2436 transfer_character_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
   2437 {
   2438   transfer_character (dtp, p, len);
   2439 }
   2440 
   2441 void
   2442 transfer_character_wide (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
   2443 {
   2444   static char *empty_string[0];
   2445 
   2446   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2447     return;
   2448 
   2449   /* Strings of zero length can have p == NULL, which confuses the
   2450      transfer routines into thinking we need more data elements.  To avoid
   2451      this, we give them a nice pointer.  */
   2452   if (len == 0 && p == NULL)
   2453     p = empty_string;
   2454 
   2455   /* Here we pass the actual kind value.  */
   2456   wrap_scalar_transfer (dtp, BT_CHARACTER, p, kind, len, 1);
   2457 }
   2458 
   2459 void
   2460 transfer_character_wide_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
   2461 {
   2462   transfer_character_wide (dtp, p, len, kind);
   2463 }
   2464 
   2465 void
   2466 transfer_complex (st_parameter_dt *dtp, void *p, int kind)
   2467 {
   2468   size_t size;
   2469   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2470     return;
   2471   size = size_from_complex_kind (kind);
   2472   wrap_scalar_transfer (dtp, BT_COMPLEX, p, kind, size, 1);
   2473 }
   2474 
   2475 void
   2476 transfer_complex_write (st_parameter_dt *dtp, void *p, int kind)
   2477 {
   2478   transfer_complex (dtp, p, kind);
   2479 }
   2480 
   2481 void
   2482 transfer_array_inner (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
   2483 		      gfc_charlen_type charlen)
   2484 {
   2485   index_type count[GFC_MAX_DIMENSIONS];
   2486   index_type extent[GFC_MAX_DIMENSIONS];
   2487   index_type stride[GFC_MAX_DIMENSIONS];
   2488   index_type stride0, rank, size, n;
   2489   size_t tsize;
   2490   char *data;
   2491   bt iotype;
   2492 
   2493   /* Adjust item_count before emitting error message.  */
   2494 
   2495   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2496     return;
   2497 
   2498   iotype = (bt) GFC_DESCRIPTOR_TYPE (desc);
   2499   size = iotype == BT_CHARACTER ? charlen : GFC_DESCRIPTOR_SIZE (desc);
   2500 
   2501   rank = GFC_DESCRIPTOR_RANK (desc);
   2502 
   2503   for (n = 0; n < rank; n++)
   2504     {
   2505       count[n] = 0;
   2506       stride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(desc,n);
   2507       extent[n] = GFC_DESCRIPTOR_EXTENT(desc,n);
   2508 
   2509       /* If the extent of even one dimension is zero, then the entire
   2510 	 array section contains zero elements, so we return after writing
   2511 	 a zero array record.  */
   2512       if (extent[n] <= 0)
   2513 	{
   2514 	  data = NULL;
   2515 	  tsize = 0;
   2516 	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
   2517 	  return;
   2518 	}
   2519     }
   2520 
   2521   stride0 = stride[0];
   2522 
   2523   /* If the innermost dimension has a stride of 1, we can do the transfer
   2524      in contiguous chunks.  */
   2525   if (stride0 == size)
   2526     tsize = extent[0];
   2527   else
   2528     tsize = 1;
   2529 
   2530   data = GFC_DESCRIPTOR_DATA (desc);
   2531 
   2532   /* When reading, we need to check endfile conditions so we do not miss
   2533      an END=label.  Make this separate so we do not have an extra test
   2534      in a tight loop when it is not needed.  */
   2535 
   2536   if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
   2537     {
   2538       while (data)
   2539 	{
   2540 	  if (unlikely (dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
   2541 	    return;
   2542 
   2543 	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
   2544 	  data += stride0 * tsize;
   2545 	  count[0] += tsize;
   2546 	  n = 0;
   2547 	  while (count[n] == extent[n])
   2548 	    {
   2549 	      count[n] = 0;
   2550 	      data -= stride[n] * extent[n];
   2551 	      n++;
   2552 	      if (n == rank)
   2553 		{
   2554 		  data = NULL;
   2555 		  break;
   2556 		}
   2557 	      else
   2558 		{
   2559 		  count[n]++;
   2560 		  data += stride[n];
   2561 		}
   2562 	    }
   2563 	}
   2564     }
   2565   else
   2566     {
   2567       while (data)
   2568 	{
   2569 	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
   2570 	  data += stride0 * tsize;
   2571 	  count[0] += tsize;
   2572 	  n = 0;
   2573 	  while (count[n] == extent[n])
   2574 	    {
   2575 	      count[n] = 0;
   2576 	      data -= stride[n] * extent[n];
   2577 	      n++;
   2578 	      if (n == rank)
   2579 		{
   2580 		  data = NULL;
   2581 		  break;
   2582 		}
   2583 	      else
   2584 		{
   2585 		  count[n]++;
   2586 		  data += stride[n];
   2587 		}
   2588 	    }
   2589 	}
   2590     }
   2591 }
   2592 
   2593 void
   2594 transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
   2595 	        gfc_charlen_type charlen)
   2596 {
   2597   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2598     return;
   2599 
   2600   if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
   2601     {
   2602       if (dtp->u.p.async)
   2603 	{
   2604 	  transfer_args args;
   2605 	  size_t sz = sizeof (gfc_array_char)
   2606 			+ sizeof (descriptor_dimension)
   2607        			* GFC_DESCRIPTOR_RANK (desc);
   2608 	  args.array.desc = xmalloc (sz);
   2609 	  NOTE ("desc = %p", (void *) args.array.desc);
   2610 	  memcpy (args.array.desc, desc, sz);
   2611 	  args.array.kind = kind;
   2612 	  args.array.charlen = charlen;
   2613 	  enqueue_transfer (dtp->u.p.current_unit->au, &args,
   2614 			    AIO_TRANSFER_ARRAY);
   2615 	  return;
   2616 	}
   2617     }
   2618   /* Come here if there was no asynchronous I/O to be scheduled.  */
   2619   transfer_array_inner (dtp, desc, kind, charlen);
   2620 }
   2621 
   2622 
   2623 void
   2624 transfer_array_write (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
   2625 		      gfc_charlen_type charlen)
   2626 {
   2627   transfer_array (dtp, desc, kind, charlen);
   2628 }
   2629 
   2630 
   2631 /* User defined input/output iomsg. */
   2632 
   2633 #define IOMSG_LEN 256
   2634 
   2635 void
   2636 transfer_derived (st_parameter_dt *parent, void *dtio_source, void *dtio_proc)
   2637 {
   2638   if (parent->u.p.current_unit)
   2639     {
   2640       if (parent->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   2641 	parent->u.p.ufdtio_ptr = (unformatted_dtio) dtio_proc;
   2642       else
   2643 	parent->u.p.fdtio_ptr = (formatted_dtio) dtio_proc;
   2644     }
   2645   wrap_scalar_transfer (parent, BT_CLASS, dtio_source, 0, 0, 1);
   2646 }
   2647 
   2648 
   2649 /* Preposition a sequential unformatted file while reading.  */
   2650 
   2651 static void
   2652 us_read (st_parameter_dt *dtp, int continued)
   2653 {
   2654   ssize_t n, nr;
   2655   GFC_INTEGER_4 i4;
   2656   GFC_INTEGER_8 i8;
   2657   gfc_offset i;
   2658 
   2659   if (compile_options.record_marker == 0)
   2660     n = sizeof (GFC_INTEGER_4);
   2661   else
   2662     n = compile_options.record_marker;
   2663 
   2664   nr = sread (dtp->u.p.current_unit->s, &i, n);
   2665   if (unlikely (nr < 0))
   2666     {
   2667       generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
   2668       return;
   2669     }
   2670   else if (nr == 0)
   2671     {
   2672       hit_eof (dtp);
   2673       return;  /* end of file */
   2674     }
   2675   else if (unlikely (n != nr))
   2676     {
   2677       generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
   2678       return;
   2679     }
   2680 
   2681   /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here.  */
   2682   if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
   2683     {
   2684       switch (nr)
   2685 	{
   2686 	case sizeof(GFC_INTEGER_4):
   2687 	  memcpy (&i4, &i, sizeof (i4));
   2688 	  i = i4;
   2689 	  break;
   2690 
   2691 	case sizeof(GFC_INTEGER_8):
   2692 	  memcpy (&i8, &i, sizeof (i8));
   2693 	  i = i8;
   2694 	  break;
   2695 
   2696 	default:
   2697 	  runtime_error ("Illegal value for record marker");
   2698 	  break;
   2699 	}
   2700     }
   2701   else
   2702     {
   2703       uint32_t u32;
   2704       uint64_t u64;
   2705       switch (nr)
   2706 	{
   2707 	case sizeof(GFC_INTEGER_4):
   2708 	  memcpy (&u32, &i, sizeof (u32));
   2709 	  u32 = __builtin_bswap32 (u32);
   2710 	  memcpy (&i4, &u32, sizeof (i4));
   2711 	  i = i4;
   2712 	  break;
   2713 
   2714 	case sizeof(GFC_INTEGER_8):
   2715 	  memcpy (&u64, &i, sizeof (u64));
   2716 	  u64 = __builtin_bswap64 (u64);
   2717 	  memcpy (&i8, &u64, sizeof (i8));
   2718 	  i = i8;
   2719 	  break;
   2720 
   2721 	default:
   2722 	  runtime_error ("Illegal value for record marker");
   2723 	  break;
   2724 	}
   2725     }
   2726 
   2727   if (i >= 0)
   2728     {
   2729       dtp->u.p.current_unit->bytes_left_subrecord = i;
   2730       dtp->u.p.current_unit->continued = 0;
   2731     }
   2732   else
   2733     {
   2734       dtp->u.p.current_unit->bytes_left_subrecord = -i;
   2735       dtp->u.p.current_unit->continued = 1;
   2736     }
   2737 
   2738   if (! continued)
   2739     dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   2740 }
   2741 
   2742 
   2743 /* Preposition a sequential unformatted file while writing.  This
   2744    amount to writing a bogus length that will be filled in later.  */
   2745 
   2746 static void
   2747 us_write (st_parameter_dt *dtp, int continued)
   2748 {
   2749   ssize_t nbytes;
   2750   gfc_offset dummy;
   2751 
   2752   dummy = 0;
   2753 
   2754   if (compile_options.record_marker == 0)
   2755     nbytes = sizeof (GFC_INTEGER_4);
   2756   else
   2757     nbytes = compile_options.record_marker ;
   2758 
   2759   if (swrite (dtp->u.p.current_unit->s, &dummy, nbytes) != nbytes)
   2760     generate_error (&dtp->common, LIBERROR_OS, NULL);
   2761 
   2762   /* For sequential unformatted, if RECL= was not specified in the OPEN
   2763      we write until we have more bytes than can fit in the subrecord
   2764      markers, then we write a new subrecord.  */
   2765 
   2766   dtp->u.p.current_unit->bytes_left_subrecord =
   2767     dtp->u.p.current_unit->recl_subrecord;
   2768   dtp->u.p.current_unit->continued = continued;
   2769 }
   2770 
   2771 
   2772 /* Position to the next record prior to transfer.  We are assumed to
   2773    be before the next record.  We also calculate the bytes in the next
   2774    record.  */
   2775 
   2776 static void
   2777 pre_position (st_parameter_dt *dtp)
   2778 {
   2779   if (dtp->u.p.current_unit->current_record)
   2780     return;			/* Already positioned.  */
   2781 
   2782   switch (current_mode (dtp))
   2783     {
   2784     case FORMATTED_STREAM:
   2785     case UNFORMATTED_STREAM:
   2786       /* There are no records with stream I/O.  If the position was specified
   2787 	 data_transfer_init has already positioned the file. If no position
   2788 	 was specified, we continue from where we last left off.  I.e.
   2789 	 there is nothing to do here.  */
   2790       break;
   2791 
   2792     case UNFORMATTED_SEQUENTIAL:
   2793       if (dtp->u.p.mode == READING)
   2794 	us_read (dtp, 0);
   2795       else
   2796 	us_write (dtp, 0);
   2797 
   2798       break;
   2799 
   2800     case FORMATTED_SEQUENTIAL:
   2801     case FORMATTED_DIRECT:
   2802     case UNFORMATTED_DIRECT:
   2803       dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   2804       break;
   2805     }
   2806 
   2807   dtp->u.p.current_unit->current_record = 1;
   2808 }
   2809 
   2810 
   2811 /* Initialize things for a data transfer.  This code is common for
   2812    both reading and writing.  */
   2813 
   2814 static void
   2815 data_transfer_init (st_parameter_dt *dtp, int read_flag)
   2816 {
   2817   unit_flags u_flags;  /* Used for creating a unit if needed.  */
   2818   GFC_INTEGER_4 cf = dtp->common.flags;
   2819   namelist_info *ionml;
   2820   async_unit *au;
   2821 
   2822   NOTE ("data_transfer_init");
   2823 
   2824   ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL;
   2825 
   2826   memset (&dtp->u.p, 0, sizeof (dtp->u.p));
   2827 
   2828   dtp->u.p.ionml = ionml;
   2829   dtp->u.p.mode = read_flag ? READING : WRITING;
   2830   dtp->u.p.namelist_mode = 0;
   2831   dtp->u.p.cc.len = 0;
   2832 
   2833   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2834     return;
   2835 
   2836   dtp->u.p.current_unit = get_unit (dtp, 1);
   2837 
   2838   if (dtp->u.p.current_unit == NULL)
   2839     {
   2840       /* This means we tried to access an external unit < 0 without
   2841 	 having opened it first with NEWUNIT=.  */
   2842       generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   2843 		      "Unit number is negative and unit was not already "
   2844 		      "opened with OPEN(NEWUNIT=...)");
   2845       return;
   2846     }
   2847   else if (dtp->u.p.current_unit->s == NULL)
   2848     {  /* Open the unit with some default flags.  */
   2849       st_parameter_open opp;
   2850       unit_convert conv;
   2851       NOTE ("Open the unit with some default flags.");
   2852       memset (&u_flags, '\0', sizeof (u_flags));
   2853       u_flags.access = ACCESS_SEQUENTIAL;
   2854       u_flags.action = ACTION_READWRITE;
   2855 
   2856       /* Is it unformatted?  */
   2857       if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
   2858 		  | IOPARM_DT_IONML_SET)))
   2859 	u_flags.form = FORM_UNFORMATTED;
   2860       else
   2861 	u_flags.form = FORM_UNSPECIFIED;
   2862 
   2863       u_flags.delim = DELIM_UNSPECIFIED;
   2864       u_flags.blank = BLANK_UNSPECIFIED;
   2865       u_flags.pad = PAD_UNSPECIFIED;
   2866       u_flags.decimal = DECIMAL_UNSPECIFIED;
   2867       u_flags.encoding = ENCODING_UNSPECIFIED;
   2868       u_flags.async = ASYNC_UNSPECIFIED;
   2869       u_flags.round = ROUND_UNSPECIFIED;
   2870       u_flags.sign = SIGN_UNSPECIFIED;
   2871       u_flags.share = SHARE_UNSPECIFIED;
   2872       u_flags.cc = CC_UNSPECIFIED;
   2873       u_flags.readonly = 0;
   2874 
   2875       u_flags.status = STATUS_UNKNOWN;
   2876 
   2877       conv = get_unformatted_convert (dtp->common.unit);
   2878 
   2879       if (conv == GFC_CONVERT_NONE)
   2880 	conv = compile_options.convert;
   2881 
   2882       switch (conv)
   2883 	{
   2884 	case GFC_CONVERT_NATIVE:
   2885 	case GFC_CONVERT_SWAP:
   2886 	  break;
   2887 
   2888 	case GFC_CONVERT_BIG:
   2889 	  conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
   2890 	  break;
   2891 
   2892 	case GFC_CONVERT_LITTLE:
   2893 	  conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
   2894 	  break;
   2895 
   2896 	default:
   2897 	  internal_error (&opp.common, "Illegal value for CONVERT");
   2898 	  break;
   2899 	}
   2900 
   2901       u_flags.convert = conv;
   2902 
   2903       opp.common = dtp->common;
   2904       opp.common.flags &= IOPARM_COMMON_MASK;
   2905       dtp->u.p.current_unit = new_unit (&opp, dtp->u.p.current_unit, &u_flags);
   2906       dtp->common.flags &= ~IOPARM_COMMON_MASK;
   2907       dtp->common.flags |= (opp.common.flags & IOPARM_COMMON_MASK);
   2908       if (dtp->u.p.current_unit == NULL)
   2909 	return;
   2910     }
   2911 
   2912   if (dtp->u.p.current_unit->child_dtio == 0)
   2913     {
   2914       if ((cf & IOPARM_DT_HAS_SIZE) != 0)
   2915 	{
   2916 	  dtp->u.p.current_unit->has_size = true;
   2917 	  /* Initialize the count.  */
   2918 	  dtp->u.p.current_unit->size_used = 0;
   2919 	}
   2920       else
   2921 	dtp->u.p.current_unit->has_size = false;
   2922     }
   2923   else if (dtp->u.p.current_unit->internal_unit_kind > 0)
   2924     dtp->u.p.unit_is_internal = 1;
   2925 
   2926   if ((cf & IOPARM_DT_HAS_ASYNCHRONOUS) != 0)
   2927     {
   2928       int f;
   2929       f = find_option (&dtp->common, dtp->asynchronous, dtp->asynchronous_len,
   2930 		       async_opt, "Bad ASYNCHRONOUS in data transfer "
   2931 		       "statement");
   2932       if (f == ASYNC_YES && dtp->u.p.current_unit->flags.async != ASYNC_YES)
   2933 	{
   2934 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   2935 			  "ASYNCHRONOUS transfer without "
   2936 			  "ASYHCRONOUS='YES' in OPEN");
   2937 	  return;
   2938 	}
   2939       dtp->u.p.async = f == ASYNC_YES;
   2940     }
   2941 
   2942   au = dtp->u.p.current_unit->au;
   2943   if (au)
   2944     {
   2945       if (dtp->u.p.async)
   2946 	{
   2947 	  /* If this is an asynchronous I/O statement, collect errors and
   2948 	     return if there are any.  */
   2949 	  if (collect_async_errors (&dtp->common, au))
   2950 	    return;
   2951 	}
   2952       else
   2953 	{
   2954 	  /* Synchronous statement: Perform a wait operation for any pending
   2955 	     asynchronous I/O.  This needs to be done before all other error
   2956 	     checks.  See F2008, 9.6.4.1.  */
   2957 	  if (async_wait (&(dtp->common), au))
   2958 	    return;
   2959 	}
   2960     }
   2961 
   2962   /* Check the action.  */
   2963 
   2964   if (read_flag && dtp->u.p.current_unit->flags.action == ACTION_WRITE)
   2965     {
   2966       generate_error (&dtp->common, LIBERROR_BAD_ACTION,
   2967 		      "Cannot read from file opened for WRITE");
   2968       return;
   2969     }
   2970 
   2971   if (!read_flag && dtp->u.p.current_unit->flags.action == ACTION_READ)
   2972     {
   2973       generate_error (&dtp->common, LIBERROR_BAD_ACTION,
   2974 		      "Cannot write to file opened for READ");
   2975       return;
   2976     }
   2977 
   2978   dtp->u.p.first_item = 1;
   2979 
   2980   /* Check the format.  */
   2981 
   2982   if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
   2983     parse_format (dtp);
   2984 
   2985   if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
   2986       && (cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
   2987 	 != 0)
   2988     {
   2989       generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   2990 		      "Format present for UNFORMATTED data transfer");
   2991       return;
   2992     }
   2993 
   2994   if ((cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0 && dtp->u.p.ionml != NULL)
   2995      {
   2996 	if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
   2997 	  {
   2998 	    generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   2999 			"A format cannot be specified with a namelist");
   3000 	    return;
   3001 	  }
   3002      }
   3003   else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
   3004 	   !(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT)))
   3005     {
   3006       generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3007 		      "Missing format for FORMATTED data transfer");
   3008       return;
   3009     }
   3010 
   3011   if (is_internal_unit (dtp)
   3012       && dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   3013     {
   3014       generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3015 		      "Internal file cannot be accessed by UNFORMATTED "
   3016 		      "data transfer");
   3017       return;
   3018     }
   3019 
   3020   /* Check the record or position number.  */
   3021 
   3022   if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT
   3023       && (cf & IOPARM_DT_HAS_REC) == 0)
   3024     {
   3025       generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
   3026 		      "Direct access data transfer requires record number");
   3027       return;
   3028     }
   3029 
   3030   if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
   3031     {
   3032       if ((cf & IOPARM_DT_HAS_REC) != 0)
   3033 	{
   3034 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3035 			"Record number not allowed for sequential access "
   3036 			"data transfer");
   3037 	  return;
   3038 	}
   3039 
   3040       if (compile_options.warn_std &&
   3041 	  dtp->u.p.current_unit->endfile == AFTER_ENDFILE)
   3042       	{
   3043 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3044 			"Sequential READ or WRITE not allowed after "
   3045 			"EOF marker, possibly use REWIND or BACKSPACE");
   3046 	  return;
   3047 	}
   3048     }
   3049 
   3050   /* Process the ADVANCE option.  */
   3051 
   3052   dtp->u.p.advance_status
   3053     = !(cf & IOPARM_DT_HAS_ADVANCE) ? ADVANCE_UNSPECIFIED :
   3054       find_option (&dtp->common, dtp->advance, dtp->advance_len, advance_opt,
   3055 		   "Bad ADVANCE parameter in data transfer statement");
   3056 
   3057   if (dtp->u.p.advance_status != ADVANCE_UNSPECIFIED)
   3058     {
   3059       if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
   3060 	{
   3061 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3062 			  "ADVANCE specification conflicts with sequential "
   3063 			  "access");
   3064 	  return;
   3065 	}
   3066 
   3067       if (is_internal_unit (dtp))
   3068 	{
   3069 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3070 			  "ADVANCE specification conflicts with internal file");
   3071 	  return;
   3072 	}
   3073 
   3074       if ((cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
   3075 	  != IOPARM_DT_HAS_FORMAT)
   3076 	{
   3077 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3078 			  "ADVANCE specification requires an explicit format");
   3079 	  return;
   3080 	}
   3081     }
   3082 
   3083   /* Child IO is non-advancing and any ADVANCE= specifier is ignored.
   3084      F2008 9.6.2.4  */
   3085   if (dtp->u.p.current_unit->child_dtio  > 0)
   3086     dtp->u.p.advance_status = ADVANCE_NO;
   3087 
   3088   if (read_flag)
   3089     {
   3090       dtp->u.p.current_unit->previous_nonadvancing_write = 0;
   3091 
   3092       if ((cf & IOPARM_EOR) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
   3093 	{
   3094 	  generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
   3095 			  "EOR specification requires an ADVANCE specification "
   3096 			  "of NO");
   3097 	  return;
   3098 	}
   3099 
   3100       if ((cf & IOPARM_DT_HAS_SIZE) != 0
   3101 	  && dtp->u.p.advance_status != ADVANCE_NO)
   3102 	{
   3103 	  generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
   3104 			  "SIZE specification requires an ADVANCE "
   3105 			  "specification of NO");
   3106 	  return;
   3107 	}
   3108     }
   3109   else
   3110     {				/* Write constraints.  */
   3111       if ((cf & IOPARM_END) != 0)
   3112 	{
   3113 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3114 			  "END specification cannot appear in a write "
   3115 			  "statement");
   3116 	  return;
   3117 	}
   3118 
   3119       if ((cf & IOPARM_EOR) != 0)
   3120 	{
   3121 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3122 			  "EOR specification cannot appear in a write "
   3123 			  "statement");
   3124 	  return;
   3125 	}
   3126 
   3127       if ((cf & IOPARM_DT_HAS_SIZE) != 0)
   3128 	{
   3129 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3130 			  "SIZE specification cannot appear in a write "
   3131 			  "statement");
   3132 	  return;
   3133 	}
   3134     }
   3135 
   3136   if (dtp->u.p.advance_status == ADVANCE_UNSPECIFIED)
   3137     dtp->u.p.advance_status = ADVANCE_YES;
   3138 
   3139   /* Check the decimal mode.  */
   3140   dtp->u.p.current_unit->decimal_status
   3141 	= !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
   3142 	  find_option (&dtp->common, dtp->decimal, dtp->decimal_len,
   3143 			decimal_opt, "Bad DECIMAL parameter in data transfer "
   3144 			"statement");
   3145 
   3146   if (dtp->u.p.current_unit->decimal_status == DECIMAL_UNSPECIFIED)
   3147 	dtp->u.p.current_unit->decimal_status = dtp->u.p.current_unit->flags.decimal;
   3148 
   3149   /* Check the round mode.  */
   3150   dtp->u.p.current_unit->round_status
   3151 	= !(cf & IOPARM_DT_HAS_ROUND) ? ROUND_UNSPECIFIED :
   3152 	  find_option (&dtp->common, dtp->round, dtp->round_len,
   3153 			round_opt, "Bad ROUND parameter in data transfer "
   3154 			"statement");
   3155 
   3156   if (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED)
   3157 	dtp->u.p.current_unit->round_status = dtp->u.p.current_unit->flags.round;
   3158 
   3159   /* Check the sign mode. */
   3160   dtp->u.p.sign_status
   3161 	= !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
   3162 	  find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt,
   3163 			"Bad SIGN parameter in data transfer statement");
   3164 
   3165   if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
   3166 	dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;
   3167 
   3168   /* Check the blank mode.  */
   3169   dtp->u.p.blank_status
   3170 	= !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
   3171 	  find_option (&dtp->common, dtp->blank, dtp->blank_len,
   3172 			blank_opt,
   3173 			"Bad BLANK parameter in data transfer statement");
   3174 
   3175   if (dtp->u.p.blank_status == BLANK_UNSPECIFIED)
   3176 	dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;
   3177 
   3178   /* Check the delim mode.  */
   3179   dtp->u.p.current_unit->delim_status
   3180 	= !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
   3181 	  find_option (&dtp->common, dtp->delim, dtp->delim_len,
   3182 	  delim_opt, "Bad DELIM parameter in data transfer statement");
   3183 
   3184   if (dtp->u.p.current_unit->delim_status == DELIM_UNSPECIFIED)
   3185     {
   3186       if (ionml && dtp->u.p.current_unit->flags.delim == DELIM_UNSPECIFIED)
   3187 	dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
   3188       else
   3189 	dtp->u.p.current_unit->delim_status = dtp->u.p.current_unit->flags.delim;
   3190     }
   3191 
   3192   /* Check the pad mode.  */
   3193   dtp->u.p.current_unit->pad_status
   3194 	= !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
   3195 	  find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt,
   3196 			"Bad PAD parameter in data transfer statement");
   3197 
   3198   if (dtp->u.p.current_unit->pad_status == PAD_UNSPECIFIED)
   3199 	dtp->u.p.current_unit->pad_status = dtp->u.p.current_unit->flags.pad;
   3200 
   3201   /* Set up the subroutine that will handle the transfers.  */
   3202 
   3203   if (read_flag)
   3204     {
   3205       if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   3206 	dtp->u.p.transfer = unformatted_read;
   3207       else
   3208 	{
   3209 	  if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
   3210 	    dtp->u.p.transfer = list_formatted_read;
   3211 	  else
   3212 	    dtp->u.p.transfer = formatted_transfer;
   3213 	}
   3214     }
   3215   else
   3216     {
   3217       if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   3218 	dtp->u.p.transfer = unformatted_write;
   3219       else
   3220 	{
   3221 	  if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
   3222 	    dtp->u.p.transfer = list_formatted_write;
   3223 	  else
   3224 	    dtp->u.p.transfer = formatted_transfer;
   3225 	}
   3226     }
   3227 
   3228   if (au && dtp->u.p.async)
   3229     {
   3230       NOTE ("enqueue_data_transfer");
   3231       enqueue_data_transfer_init (au, dtp, read_flag);
   3232     }
   3233   else
   3234     {
   3235       NOTE ("invoking data_transfer_init_worker");
   3236       data_transfer_init_worker (dtp, read_flag);
   3237     }
   3238 }
   3239 
   3240 void
   3241 data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
   3242 {
   3243   GFC_INTEGER_4 cf = dtp->common.flags;
   3244 
   3245   NOTE ("starting worker...");
   3246 
   3247   if (read_flag && dtp->u.p.current_unit->flags.form != FORM_UNFORMATTED
   3248       && ((cf & IOPARM_DT_LIST_FORMAT) != 0)
   3249       && dtp->u.p.current_unit->child_dtio  == 0)
   3250     dtp->u.p.current_unit->last_char = EOF - 1;
   3251 
   3252   /* Check to see if we might be reading what we wrote before  */
   3253 
   3254   if (dtp->u.p.mode != dtp->u.p.current_unit->mode
   3255       && !is_internal_unit (dtp))
   3256     {
   3257       int pos = fbuf_reset (dtp->u.p.current_unit);
   3258       if (pos != 0)
   3259         sseek (dtp->u.p.current_unit->s, pos, SEEK_CUR);
   3260       sflush(dtp->u.p.current_unit->s);
   3261     }
   3262 
   3263   /* Check the POS= specifier: that it is in range and that it is used with a
   3264      unit that has been connected for STREAM access. F2003 9.5.1.10.  */
   3265 
   3266   if (((cf & IOPARM_DT_HAS_POS) != 0))
   3267     {
   3268       if (is_stream_io (dtp))
   3269         {
   3270 
   3271           if (dtp->pos <= 0)
   3272             {
   3273               generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3274                               "POS=specifier must be positive");
   3275               return;
   3276             }
   3277 
   3278           if (dtp->pos >= dtp->u.p.current_unit->maxrec)
   3279             {
   3280               generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3281                               "POS=specifier too large");
   3282               return;
   3283             }
   3284 
   3285           dtp->rec = dtp->pos;
   3286 
   3287           if (dtp->u.p.mode == READING)
   3288             {
   3289               /* Reset the endfile flag; if we hit EOF during reading
   3290                  we'll set the flag and generate an error at that point
   3291                  rather than worrying about it here.  */
   3292               dtp->u.p.current_unit->endfile = NO_ENDFILE;
   3293             }
   3294 
   3295           if (dtp->pos != dtp->u.p.current_unit->strm_pos)
   3296             {
   3297               fbuf_reset (dtp->u.p.current_unit);
   3298               if (sseek (dtp->u.p.current_unit->s, dtp->pos - 1,
   3299 		  SEEK_SET) < 0)
   3300                 {
   3301                   generate_error (&dtp->common, LIBERROR_OS, NULL);
   3302                   return;
   3303                 }
   3304               dtp->u.p.current_unit->strm_pos = dtp->pos;
   3305             }
   3306         }
   3307       else
   3308         {
   3309           generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3310                           "POS=specifier not allowed, "
   3311                           "Try OPEN with ACCESS='stream'");
   3312           return;
   3313         }
   3314     }
   3315 
   3316 
   3317   /* Sanity checks on the record number.  */
   3318   if ((cf & IOPARM_DT_HAS_REC) != 0)
   3319     {
   3320       if (dtp->rec <= 0)
   3321 	{
   3322 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3323 			  "Record number must be positive");
   3324 	  return;
   3325 	}
   3326 
   3327       if (dtp->rec >= dtp->u.p.current_unit->maxrec)
   3328 	{
   3329 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3330 			  "Record number too large");
   3331 	  return;
   3332 	}
   3333 
   3334       /* Make sure format buffer is reset.  */
   3335       if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
   3336         fbuf_reset (dtp->u.p.current_unit);
   3337 
   3338 
   3339       /* Check whether the record exists to be read.  Only
   3340 	 a partial record needs to exist.  */
   3341 
   3342       if (dtp->u.p.mode == READING && (dtp->rec - 1)
   3343 	  * dtp->u.p.current_unit->recl >= ssize (dtp->u.p.current_unit->s))
   3344 	{
   3345 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3346 			  "Non-existing record number");
   3347 	  return;
   3348 	}
   3349 
   3350       /* Position the file.  */
   3351       if (sseek (dtp->u.p.current_unit->s, (gfc_offset) (dtp->rec - 1)
   3352 		 * dtp->u.p.current_unit->recl, SEEK_SET) < 0)
   3353 	{
   3354 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
   3355 	  return;
   3356 	}
   3357 
   3358       if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
   3359        {
   3360          generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3361                      "Record number not allowed for stream access "
   3362                      "data transfer");
   3363          return;
   3364        }
   3365     }
   3366 
   3367   /* Bugware for badly written mixed C-Fortran I/O.  */
   3368   if (!is_internal_unit (dtp))
   3369     flush_if_preconnected(dtp->u.p.current_unit->s);
   3370 
   3371   dtp->u.p.current_unit->mode = dtp->u.p.mode;
   3372 
   3373   /* Set the maximum position reached from the previous I/O operation.  This
   3374      could be greater than zero from a previous non-advancing write.  */
   3375   dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
   3376 
   3377   pre_position (dtp);
   3378 
   3379   /* Make sure that we don't do a read after a nonadvancing write.  */
   3380 
   3381   if (read_flag)
   3382     {
   3383       if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
   3384 	{
   3385 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3386 			  "Cannot READ after a nonadvancing WRITE");
   3387 	  return;
   3388 	}
   3389     }
   3390   else
   3391     {
   3392       if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
   3393 	dtp->u.p.current_unit->read_bad = 1;
   3394     }
   3395 
   3396   if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
   3397     {
   3398 #ifdef HAVE_USELOCALE
   3399       dtp->u.p.old_locale = uselocale (c_locale);
   3400 #else
   3401       __gthread_mutex_lock (&old_locale_lock);
   3402       if (!old_locale_ctr++)
   3403 	{
   3404 	  old_locale = setlocale (LC_NUMERIC, NULL);
   3405 	  setlocale (LC_NUMERIC, "C");
   3406 	}
   3407       __gthread_mutex_unlock (&old_locale_lock);
   3408 #endif
   3409       /* Start the data transfer if we are doing a formatted transfer.  */
   3410       if ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0
   3411 	&& dtp->u.p.ionml == NULL)
   3412 	formatted_transfer (dtp, 0, NULL, 0, 0, 1);
   3413     }
   3414 }
   3415 
   3416 
   3417 /* Initialize an array_loop_spec given the array descriptor.  The function
   3418    returns the index of the last element of the array, and also returns
   3419    starting record, where the first I/O goes to (necessary in case of
   3420    negative strides).  */
   3421 
   3422 gfc_offset
   3423 init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
   3424 		gfc_offset *start_record)
   3425 {
   3426   int rank = GFC_DESCRIPTOR_RANK(desc);
   3427   int i;
   3428   gfc_offset index;
   3429   int empty;
   3430 
   3431   empty = 0;
   3432   index = 1;
   3433   *start_record = 0;
   3434 
   3435   for (i=0; i<rank; i++)
   3436     {
   3437       ls[i].idx = GFC_DESCRIPTOR_LBOUND(desc,i);
   3438       ls[i].start = GFC_DESCRIPTOR_LBOUND(desc,i);
   3439       ls[i].end = GFC_DESCRIPTOR_UBOUND(desc,i);
   3440       ls[i].step = GFC_DESCRIPTOR_STRIDE(desc,i);
   3441       empty = empty || (GFC_DESCRIPTOR_UBOUND(desc,i)
   3442 			< GFC_DESCRIPTOR_LBOUND(desc,i));
   3443 
   3444       if (GFC_DESCRIPTOR_STRIDE(desc,i) > 0)
   3445 	{
   3446 	  index += (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
   3447 	    * GFC_DESCRIPTOR_STRIDE(desc,i);
   3448 	}
   3449       else
   3450 	{
   3451 	  index -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
   3452 	    * GFC_DESCRIPTOR_STRIDE(desc,i);
   3453 	  *start_record -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
   3454 	    * GFC_DESCRIPTOR_STRIDE(desc,i);
   3455 	}
   3456     }
   3457 
   3458   if (empty)
   3459     return 0;
   3460   else
   3461     return index;
   3462 }
   3463 
   3464 /* Determine the index to the next record in an internal unit array by
   3465    by incrementing through the array_loop_spec.  */
   3466 
   3467 gfc_offset
   3468 next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
   3469 {
   3470   int i, carry;
   3471   gfc_offset index;
   3472 
   3473   carry = 1;
   3474   index = 0;
   3475 
   3476   for (i = 0; i < dtp->u.p.current_unit->rank; i++)
   3477     {
   3478       if (carry)
   3479         {
   3480           ls[i].idx++;
   3481           if (ls[i].idx > ls[i].end)
   3482             {
   3483               ls[i].idx = ls[i].start;
   3484               carry = 1;
   3485             }
   3486           else
   3487             carry = 0;
   3488         }
   3489       index = index + (ls[i].idx - ls[i].start) * ls[i].step;
   3490     }
   3491 
   3492   *finished = carry;
   3493 
   3494   return index;
   3495 }
   3496 
   3497 
   3498 
   3499 /* Skip to the end of the current record, taking care of an optional
   3500    record marker of size bytes.  If the file is not seekable, we
   3501    read chunks of size MAX_READ until we get to the right
   3502    position.  */
   3503 
   3504 static void
   3505 skip_record (st_parameter_dt *dtp, gfc_offset bytes)
   3506 {
   3507   ssize_t rlength, readb;
   3508 #define MAX_READ 4096
   3509   char p[MAX_READ];
   3510 
   3511   dtp->u.p.current_unit->bytes_left_subrecord += bytes;
   3512   if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
   3513     return;
   3514 
   3515   /* Direct access files do not generate END conditions,
   3516      only I/O errors.  */
   3517   if (sseek (dtp->u.p.current_unit->s,
   3518 	     dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
   3519     {
   3520       /* Seeking failed, fall back to seeking by reading data.  */
   3521       while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
   3522 	{
   3523 	  rlength =
   3524 	    (MAX_READ < dtp->u.p.current_unit->bytes_left_subrecord) ?
   3525 	    MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
   3526 
   3527 	  readb = sread (dtp->u.p.current_unit->s, p, rlength);
   3528 	  if (readb < 0)
   3529 	    {
   3530 	      generate_error (&dtp->common, LIBERROR_OS, NULL);
   3531 	      return;
   3532 	    }
   3533 
   3534 	  dtp->u.p.current_unit->bytes_left_subrecord -= readb;
   3535 	}
   3536       return;
   3537     }
   3538   dtp->u.p.current_unit->bytes_left_subrecord = 0;
   3539 }
   3540 
   3541 
   3542 /* Advance to the next record reading unformatted files, taking
   3543    care of subrecords.  If complete_record is nonzero, we loop
   3544    until all subrecords are cleared.  */
   3545 
   3546 static void
   3547 next_record_r_unf (st_parameter_dt *dtp, int complete_record)
   3548 {
   3549   size_t bytes;
   3550 
   3551   bytes =  compile_options.record_marker == 0 ?
   3552     sizeof (GFC_INTEGER_4) : compile_options.record_marker;
   3553 
   3554   while(1)
   3555     {
   3556 
   3557       /* Skip over tail */
   3558 
   3559       skip_record (dtp, bytes);
   3560 
   3561       if ( ! (complete_record && dtp->u.p.current_unit->continued))
   3562 	return;
   3563 
   3564       us_read (dtp, 1);
   3565     }
   3566 }
   3567 
   3568 
   3569 static gfc_offset
   3570 min_off (gfc_offset a, gfc_offset b)
   3571 {
   3572   return (a < b ? a : b);
   3573 }
   3574 
   3575 
   3576 /* Space to the next record for read mode.  */
   3577 
   3578 static void
   3579 next_record_r (st_parameter_dt *dtp, int done)
   3580 {
   3581   gfc_offset record;
   3582   char p;
   3583   int cc;
   3584 
   3585   switch (current_mode (dtp))
   3586     {
   3587     /* No records in unformatted STREAM I/O.  */
   3588     case UNFORMATTED_STREAM:
   3589       return;
   3590 
   3591     case UNFORMATTED_SEQUENTIAL:
   3592       next_record_r_unf (dtp, 1);
   3593       dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3594       break;
   3595 
   3596     case FORMATTED_DIRECT:
   3597     case UNFORMATTED_DIRECT:
   3598       skip_record (dtp, dtp->u.p.current_unit->bytes_left);
   3599       break;
   3600 
   3601     case FORMATTED_STREAM:
   3602     case FORMATTED_SEQUENTIAL:
   3603       /* read_sf has already terminated input because of an '\n', or
   3604          we have hit EOF.  */
   3605       if (dtp->u.p.sf_seen_eor)
   3606 	{
   3607 	  dtp->u.p.sf_seen_eor = 0;
   3608 	  break;
   3609 	}
   3610 
   3611       if (is_internal_unit (dtp))
   3612 	{
   3613 	  if (is_array_io (dtp))
   3614 	    {
   3615 	      int finished;
   3616 
   3617 	      record = next_array_record (dtp, dtp->u.p.current_unit->ls,
   3618 					  &finished);
   3619 	      if (!done && finished)
   3620 		hit_eof (dtp);
   3621 
   3622 	      /* Now seek to this record.  */
   3623 	      record = record * dtp->u.p.current_unit->recl;
   3624 	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
   3625 		{
   3626 		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3627 		  break;
   3628 		}
   3629 	      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3630 	    }
   3631 	  else
   3632 	    {
   3633 	      gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
   3634 	      bytes_left = min_off (bytes_left,
   3635 		      ssize (dtp->u.p.current_unit->s)
   3636 		      - stell (dtp->u.p.current_unit->s));
   3637 	      if (sseek (dtp->u.p.current_unit->s,
   3638 			 bytes_left, SEEK_CUR) < 0)
   3639 	        {
   3640 		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3641 		  break;
   3642 		}
   3643 	      dtp->u.p.current_unit->bytes_left
   3644 		= dtp->u.p.current_unit->recl;
   3645 	    }
   3646 	  break;
   3647 	}
   3648       else if (dtp->u.p.current_unit->flags.cc != CC_NONE)
   3649 	{
   3650 	  do
   3651 	    {
   3652               errno = 0;
   3653               cc = fbuf_getc (dtp->u.p.current_unit);
   3654 	      if (cc == EOF)
   3655 		{
   3656                   if (errno != 0)
   3657                     generate_error (&dtp->common, LIBERROR_OS, NULL);
   3658 		  else
   3659 		    {
   3660 		      if (is_stream_io (dtp)
   3661 			  || dtp->u.p.current_unit->pad_status == PAD_NO
   3662 			  || dtp->u.p.current_unit->bytes_left
   3663 			     == dtp->u.p.current_unit->recl)
   3664 			hit_eof (dtp);
   3665 		    }
   3666 		  break;
   3667                 }
   3668 
   3669 	      if (is_stream_io (dtp))
   3670 		dtp->u.p.current_unit->strm_pos++;
   3671 
   3672               p = (char) cc;
   3673 	    }
   3674 	  while (p != '\n');
   3675 	}
   3676       break;
   3677     }
   3678 }
   3679 
   3680 
   3681 /* Small utility function to write a record marker, taking care of
   3682    byte swapping and of choosing the correct size.  */
   3683 
   3684 static int
   3685 write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
   3686 {
   3687   size_t len;
   3688   GFC_INTEGER_4 buf4;
   3689   GFC_INTEGER_8 buf8;
   3690 
   3691   if (compile_options.record_marker == 0)
   3692     len = sizeof (GFC_INTEGER_4);
   3693   else
   3694     len = compile_options.record_marker;
   3695 
   3696   /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here.  */
   3697   if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
   3698     {
   3699       switch (len)
   3700 	{
   3701 	case sizeof (GFC_INTEGER_4):
   3702 	  buf4 = buf;
   3703 	  return swrite (dtp->u.p.current_unit->s, &buf4, len);
   3704 	  break;
   3705 
   3706 	case sizeof (GFC_INTEGER_8):
   3707 	  buf8 = buf;
   3708 	  return swrite (dtp->u.p.current_unit->s, &buf8, len);
   3709 	  break;
   3710 
   3711 	default:
   3712 	  runtime_error ("Illegal value for record marker");
   3713 	  break;
   3714 	}
   3715     }
   3716   else
   3717     {
   3718       uint32_t u32;
   3719       uint64_t u64;
   3720       switch (len)
   3721 	{
   3722 	case sizeof (GFC_INTEGER_4):
   3723 	  buf4 = buf;
   3724 	  memcpy (&u32, &buf4, sizeof (u32));
   3725 	  u32 = __builtin_bswap32 (u32);
   3726 	  return swrite (dtp->u.p.current_unit->s, &u32, len);
   3727 	  break;
   3728 
   3729 	case sizeof (GFC_INTEGER_8):
   3730 	  buf8 = buf;
   3731 	  memcpy (&u64, &buf8, sizeof (u64));
   3732 	  u64 = __builtin_bswap64 (u64);
   3733 	  return swrite (dtp->u.p.current_unit->s, &u64, len);
   3734 	  break;
   3735 
   3736 	default:
   3737 	  runtime_error ("Illegal value for record marker");
   3738 	  break;
   3739 	}
   3740     }
   3741 
   3742 }
   3743 
   3744 /* Position to the next (sub)record in write mode for
   3745    unformatted sequential files.  */
   3746 
   3747 static void
   3748 next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
   3749 {
   3750   gfc_offset m, m_write, record_marker;
   3751 
   3752   /* Bytes written.  */
   3753   m = dtp->u.p.current_unit->recl_subrecord
   3754     - dtp->u.p.current_unit->bytes_left_subrecord;
   3755 
   3756   if (compile_options.record_marker == 0)
   3757     record_marker = sizeof (GFC_INTEGER_4);
   3758   else
   3759     record_marker = compile_options.record_marker;
   3760 
   3761   /* Seek to the head and overwrite the bogus length with the real
   3762      length.  */
   3763 
   3764   if (unlikely (sseek (dtp->u.p.current_unit->s, - m - record_marker,
   3765 		       SEEK_CUR) < 0))
   3766     goto io_error;
   3767 
   3768   if (next_subrecord)
   3769     m_write = -m;
   3770   else
   3771     m_write = m;
   3772 
   3773   if (unlikely (write_us_marker (dtp, m_write) < 0))
   3774     goto io_error;
   3775 
   3776   /* Seek past the end of the current record.  */
   3777 
   3778   if (unlikely (sseek (dtp->u.p.current_unit->s, m, SEEK_CUR) < 0))
   3779     goto io_error;
   3780 
   3781   /* Write the length tail.  If we finish a record containing
   3782      subrecords, we write out the negative length.  */
   3783 
   3784   if (dtp->u.p.current_unit->continued)
   3785     m_write = -m;
   3786   else
   3787     m_write = m;
   3788 
   3789   if (unlikely (write_us_marker (dtp, m_write) < 0))
   3790     goto io_error;
   3791 
   3792   return;
   3793 
   3794  io_error:
   3795   generate_error (&dtp->common, LIBERROR_OS, NULL);
   3796   return;
   3797 
   3798 }
   3799 
   3800 
   3801 /* Utility function like memset() but operating on streams. Return
   3802    value is same as for POSIX write().  */
   3803 
   3804 static gfc_offset
   3805 sset (stream *s, int c, gfc_offset nbyte)
   3806 {
   3807 #define WRITE_CHUNK 256
   3808   char p[WRITE_CHUNK];
   3809   gfc_offset bytes_left;
   3810   ssize_t trans;
   3811 
   3812   if (nbyte < WRITE_CHUNK)
   3813     memset (p, c, nbyte);
   3814   else
   3815     memset (p, c, WRITE_CHUNK);
   3816 
   3817   bytes_left = nbyte;
   3818   while (bytes_left > 0)
   3819     {
   3820       trans = (bytes_left < WRITE_CHUNK) ? bytes_left : WRITE_CHUNK;
   3821       trans = swrite (s, p, trans);
   3822       if (trans <= 0)
   3823 	return trans;
   3824       bytes_left -= trans;
   3825     }
   3826 
   3827   return nbyte - bytes_left;
   3828 }
   3829 
   3830 
   3831 /* Finish up a record according to the legacy carriagecontrol type, based
   3832    on the first character in the record.  */
   3833 
   3834 static void
   3835 next_record_cc (st_parameter_dt *dtp)
   3836 {
   3837   /* Only valid with CARRIAGECONTROL=FORTRAN.  */
   3838   if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
   3839     return;
   3840 
   3841   fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   3842   if (dtp->u.p.cc.len > 0)
   3843     {
   3844       char *p = fbuf_alloc (dtp->u.p.current_unit, dtp->u.p.cc.len);
   3845       if (!p)
   3846 	generate_error (&dtp->common, LIBERROR_OS, NULL);
   3847 
   3848       /* Output CR for the first character with default CC setting.  */
   3849       *(p++) = dtp->u.p.cc.u.end;
   3850       if (dtp->u.p.cc.len > 1)
   3851 	*p = dtp->u.p.cc.u.end;
   3852     }
   3853 }
   3854 
   3855 /* Position to the next record in write mode.  */
   3856 
   3857 static void
   3858 next_record_w (st_parameter_dt *dtp, int done)
   3859 {
   3860   gfc_offset max_pos_off;
   3861 
   3862   /* Zero counters for X- and T-editing.  */
   3863   max_pos_off = dtp->u.p.max_pos;
   3864   dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   3865 
   3866   switch (current_mode (dtp))
   3867     {
   3868     /* No records in unformatted STREAM I/O.  */
   3869     case UNFORMATTED_STREAM:
   3870       return;
   3871 
   3872     case FORMATTED_DIRECT:
   3873       if (dtp->u.p.current_unit->bytes_left == 0)
   3874 	break;
   3875 
   3876       fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   3877       fbuf_flush (dtp->u.p.current_unit, WRITING);
   3878       if (sset (dtp->u.p.current_unit->s, ' ',
   3879 		dtp->u.p.current_unit->bytes_left)
   3880 	  != dtp->u.p.current_unit->bytes_left)
   3881 	goto io_error;
   3882 
   3883       break;
   3884 
   3885     case UNFORMATTED_DIRECT:
   3886       if (dtp->u.p.current_unit->bytes_left > 0)
   3887 	{
   3888 	  gfc_offset length = dtp->u.p.current_unit->bytes_left;
   3889 	  if (sset (dtp->u.p.current_unit->s, 0, length) != length)
   3890 	    goto io_error;
   3891 	}
   3892       break;
   3893 
   3894     case UNFORMATTED_SEQUENTIAL:
   3895       next_record_w_unf (dtp, 0);
   3896       dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3897       break;
   3898 
   3899     case FORMATTED_STREAM:
   3900     case FORMATTED_SEQUENTIAL:
   3901 
   3902       if (is_internal_unit (dtp))
   3903 	{
   3904 	  char *p;
   3905 	  /* Internal unit, so must fit in memory.  */
   3906 	  size_t length, m;
   3907 	  size_t max_pos = max_pos_off;
   3908 	  if (is_array_io (dtp))
   3909 	    {
   3910 	      int finished;
   3911 
   3912 	      length = dtp->u.p.current_unit->bytes_left;
   3913 
   3914 	      /* If the farthest position reached is greater than current
   3915 	      position, adjust the position and set length to pad out
   3916 	      whats left.  Otherwise just pad whats left.
   3917 	      (for character array unit) */
   3918 	      m = dtp->u.p.current_unit->recl
   3919 			- dtp->u.p.current_unit->bytes_left;
   3920 	      if (max_pos > m)
   3921 		{
   3922 		  length = (max_pos - m);
   3923 		  if (sseek (dtp->u.p.current_unit->s,
   3924 			     length, SEEK_CUR) < 0)
   3925 		    {
   3926 		      generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3927 		      return;
   3928 		    }
   3929 		  length = ((size_t) dtp->u.p.current_unit->recl - max_pos);
   3930 		}
   3931 
   3932 	      p = write_block (dtp, length);
   3933 	      if (p == NULL)
   3934 		return;
   3935 
   3936 	      if (unlikely (is_char4_unit (dtp)))
   3937 	        {
   3938 		  gfc_char4_t *p4 = (gfc_char4_t *) p;
   3939 		  memset4 (p4, ' ', length);
   3940 		}
   3941 	      else
   3942 		memset (p, ' ', length);
   3943 
   3944 	      /* Now that the current record has been padded out,
   3945 		 determine where the next record in the array is.
   3946 		 Note that this can return a negative value, so it
   3947 		 needs to be assigned to a signed value.  */
   3948 	      gfc_offset record = next_array_record
   3949 		(dtp, dtp->u.p.current_unit->ls, &finished);
   3950 	      if (finished)
   3951 		dtp->u.p.current_unit->endfile = AT_ENDFILE;
   3952 
   3953 	      /* Now seek to this record */
   3954 	      record = record * dtp->u.p.current_unit->recl;
   3955 
   3956 	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
   3957 		{
   3958 		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3959 		  return;
   3960 		}
   3961 
   3962 	      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3963 	    }
   3964 	  else
   3965 	    {
   3966 	      length = 1;
   3967 
   3968 	      /* If this is the last call to next_record move to the farthest
   3969 		 position reached and set length to pad out the remainder
   3970 		 of the record. (for character scaler unit) */
   3971 	      if (done)
   3972 		{
   3973 		  m = dtp->u.p.current_unit->recl
   3974 			- dtp->u.p.current_unit->bytes_left;
   3975 		  if (max_pos > m)
   3976 		    {
   3977 		      length = max_pos - m;
   3978 		      if (sseek (dtp->u.p.current_unit->s,
   3979 				 length, SEEK_CUR) < 0)
   3980 		        {
   3981 			  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3982 			  return;
   3983 			}
   3984 		      length = (size_t) dtp->u.p.current_unit->recl
   3985 			- max_pos;
   3986 		    }
   3987 		  else
   3988 		    length = dtp->u.p.current_unit->bytes_left;
   3989 		}
   3990 	      if (length > 0)
   3991 		{
   3992 		  p = write_block (dtp, length);
   3993 		  if (p == NULL)
   3994 		    return;
   3995 
   3996 		  if (unlikely (is_char4_unit (dtp)))
   3997 		    {
   3998 		      gfc_char4_t *p4 = (gfc_char4_t *) p;
   3999 		      memset4 (p4, (gfc_char4_t) ' ', length);
   4000 		    }
   4001 		  else
   4002 		    memset (p, ' ', length);
   4003 		}
   4004 	    }
   4005 	}
   4006       /* Handle legacy CARRIAGECONTROL line endings.  */
   4007       else if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
   4008 	next_record_cc (dtp);
   4009       else
   4010 	{
   4011 	  /* Skip newlines for CC=CC_NONE.  */
   4012 	  const int len = (dtp->u.p.current_unit->flags.cc == CC_NONE)
   4013 	    ? 0
   4014 #ifdef HAVE_CRLF
   4015 	    : 2;
   4016 #else
   4017 	    : 1;
   4018 #endif
   4019 	  fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   4020 	  if (dtp->u.p.current_unit->flags.cc != CC_NONE)
   4021 	    {
   4022 	      char *p = fbuf_alloc (dtp->u.p.current_unit, len);
   4023 	      if (!p)
   4024 		goto io_error;
   4025 #ifdef HAVE_CRLF
   4026 	      *(p++) = '\r';
   4027 #endif
   4028 	      *p = '\n';
   4029 	    }
   4030 	  if (is_stream_io (dtp))
   4031 	    {
   4032 	      dtp->u.p.current_unit->strm_pos += len;
   4033 	      if (dtp->u.p.current_unit->strm_pos
   4034 		  < ssize (dtp->u.p.current_unit->s))
   4035 		unit_truncate (dtp->u.p.current_unit,
   4036                                dtp->u.p.current_unit->strm_pos - 1,
   4037                                &dtp->common);
   4038 	    }
   4039 	}
   4040 
   4041       break;
   4042 
   4043     io_error:
   4044       generate_error (&dtp->common, LIBERROR_OS, NULL);
   4045       break;
   4046     }
   4047 }
   4048 
   4049 /* Position to the next record, which means moving to the end of the
   4050    current record.  This can happen under several different
   4051    conditions.  If the done flag is not set, we get ready to process
   4052    the next record.  */
   4053 
   4054 void
   4055 next_record (st_parameter_dt *dtp, int done)
   4056 {
   4057   gfc_offset fp; /* File position.  */
   4058 
   4059   dtp->u.p.current_unit->read_bad = 0;
   4060 
   4061   if (dtp->u.p.mode == READING)
   4062     next_record_r (dtp, done);
   4063   else
   4064     next_record_w (dtp, done);
   4065 
   4066   fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
   4067 
   4068   if (!is_stream_io (dtp))
   4069     {
   4070       /* Since we have changed the position, set it to unspecified so
   4071 	 that INQUIRE(POSITION=) knows it needs to look into it.  */
   4072       if (done)
   4073 	dtp->u.p.current_unit->flags.position = POSITION_UNSPECIFIED;
   4074 
   4075       dtp->u.p.current_unit->current_record = 0;
   4076       if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
   4077 	{
   4078 	  fp = stell (dtp->u.p.current_unit->s);
   4079 	  /* Calculate next record, rounding up partial records.  */
   4080 	  dtp->u.p.current_unit->last_record =
   4081 	    (fp + dtp->u.p.current_unit->recl) /
   4082 	      dtp->u.p.current_unit->recl - 1;
   4083 	}
   4084       else
   4085 	dtp->u.p.current_unit->last_record++;
   4086     }
   4087 
   4088   if (!done)
   4089     pre_position (dtp);
   4090 
   4091   smarkeor (dtp->u.p.current_unit->s);
   4092 }
   4093 
   4094 
   4095 /* Finalize the current data transfer.  For a nonadvancing transfer,
   4096    this means advancing to the next record.  For internal units close the
   4097    stream associated with the unit.  */
   4098 
   4099 static void
   4100 finalize_transfer (st_parameter_dt *dtp)
   4101 {
   4102   GFC_INTEGER_4 cf = dtp->common.flags;
   4103 
   4104   if ((dtp->u.p.ionml != NULL)
   4105       && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
   4106     {
   4107        dtp->u.p.namelist_mode = 1;
   4108        if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
   4109 	 namelist_read (dtp);
   4110        else
   4111 	 namelist_write (dtp);
   4112     }
   4113 
   4114   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
   4115     *dtp->size = dtp->u.p.current_unit->size_used;
   4116 
   4117   if (dtp->u.p.eor_condition)
   4118     {
   4119       generate_error (&dtp->common, LIBERROR_EOR, NULL);
   4120       goto done;
   4121     }
   4122 
   4123   if (dtp->u.p.current_unit && (dtp->u.p.current_unit->child_dtio  > 0))
   4124     {
   4125       if (cf & IOPARM_DT_HAS_FORMAT)
   4126         {
   4127 	  free (dtp->u.p.fmt);
   4128 	  free (dtp->format);
   4129 	}
   4130       return;
   4131     }
   4132 
   4133   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   4134     {
   4135       if (dtp->u.p.current_unit && current_mode (dtp) == UNFORMATTED_SEQUENTIAL)
   4136 	dtp->u.p.current_unit->current_record = 0;
   4137       goto done;
   4138     }
   4139 
   4140   dtp->u.p.transfer = NULL;
   4141   if (dtp->u.p.current_unit == NULL)
   4142     goto done;
   4143 
   4144   if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
   4145     {
   4146       finish_list_read (dtp);
   4147       goto done;
   4148     }
   4149 
   4150   if (dtp->u.p.mode == WRITING)
   4151     dtp->u.p.current_unit->previous_nonadvancing_write
   4152       = dtp->u.p.advance_status == ADVANCE_NO;
   4153 
   4154   if (is_stream_io (dtp))
   4155     {
   4156       if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
   4157 	  && dtp->u.p.advance_status != ADVANCE_NO)
   4158 	next_record (dtp, 1);
   4159 
   4160       goto done;
   4161     }
   4162 
   4163   dtp->u.p.current_unit->current_record = 0;
   4164 
   4165   if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
   4166     {
   4167       fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
   4168       dtp->u.p.seen_dollar = 0;
   4169       goto done;
   4170     }
   4171 
   4172   /* For non-advancing I/O, save the current maximum position for use in the
   4173      next I/O operation if needed.  */
   4174   if (dtp->u.p.advance_status == ADVANCE_NO)
   4175     {
   4176       if (dtp->u.p.skips > 0)
   4177 	{
   4178 	  int tmp;
   4179 	  write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
   4180 	  tmp = (int)(dtp->u.p.current_unit->recl
   4181 		      - dtp->u.p.current_unit->bytes_left);
   4182 	  dtp->u.p.max_pos =
   4183 	    dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
   4184 	  dtp->u.p.skips = 0;
   4185 	}
   4186       int bytes_written = (int) (dtp->u.p.current_unit->recl
   4187 	- dtp->u.p.current_unit->bytes_left);
   4188       dtp->u.p.current_unit->saved_pos =
   4189 	dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
   4190       fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
   4191       goto done;
   4192     }
   4193   else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
   4194            && dtp->u.p.mode == WRITING && !is_internal_unit (dtp))
   4195       fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   4196 
   4197   dtp->u.p.current_unit->saved_pos = 0;
   4198   dtp->u.p.current_unit->last_char = EOF - 1;
   4199   next_record (dtp, 1);
   4200 
   4201  done:
   4202 
   4203   if (dtp->u.p.unit_is_internal)
   4204     {
   4205       /* The unit structure may be reused later so clear the
   4206 	 internal unit kind.  */
   4207       dtp->u.p.current_unit->internal_unit_kind = 0;
   4208 
   4209       fbuf_destroy (dtp->u.p.current_unit);
   4210       if (dtp->u.p.current_unit
   4211 	  && (dtp->u.p.current_unit->child_dtio  == 0)
   4212 	  && dtp->u.p.current_unit->s)
   4213 	{
   4214 	  sclose (dtp->u.p.current_unit->s);
   4215 	  dtp->u.p.current_unit->s = NULL;
   4216 	}
   4217     }
   4218 
   4219 #ifdef HAVE_USELOCALE
   4220   if (dtp->u.p.old_locale != (locale_t) 0)
   4221     {
   4222       uselocale (dtp->u.p.old_locale);
   4223       dtp->u.p.old_locale = (locale_t) 0;
   4224     }
   4225 #else
   4226   __gthread_mutex_lock (&old_locale_lock);
   4227   if (!--old_locale_ctr)
   4228     {
   4229       setlocale (LC_NUMERIC, old_locale);
   4230       old_locale = NULL;
   4231     }
   4232   __gthread_mutex_unlock (&old_locale_lock);
   4233 #endif
   4234 }
   4235 
   4236 /* Transfer function for IOLENGTH. It doesn't actually do any
   4237    data transfer, it just updates the length counter.  */
   4238 
   4239 static void
   4240 iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
   4241 		   void *dest __attribute__ ((unused)),
   4242 		   int kind __attribute__((unused)),
   4243 		   size_t size, size_t nelems)
   4244 {
   4245   if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
   4246     *dtp->iolength += (GFC_IO_INT) (size * nelems);
   4247 }
   4248 
   4249 
   4250 /* Initialize the IOLENGTH data transfer. This function is in essence
   4251    a very much simplified version of data_transfer_init(), because it
   4252    doesn't have to deal with units at all.  */
   4253 
   4254 static void
   4255 iolength_transfer_init (st_parameter_dt *dtp)
   4256 {
   4257   if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
   4258     *dtp->iolength = 0;
   4259 
   4260   memset (&dtp->u.p, 0, sizeof (dtp->u.p));
   4261 
   4262   /* Set up the subroutine that will handle the transfers.  */
   4263 
   4264   dtp->u.p.transfer = iolength_transfer;
   4265 }
   4266 
   4267 
   4268 /* Library entry point for the IOLENGTH form of the INQUIRE
   4269    statement. The IOLENGTH form requires no I/O to be performed, but
   4270    it must still be a runtime library call so that we can determine
   4271    the iolength for dynamic arrays and such.  */
   4272 
   4273 extern void st_iolength (st_parameter_dt *);
   4274 export_proto(st_iolength);
   4275 
   4276 void
   4277 st_iolength (st_parameter_dt *dtp)
   4278 {
   4279   library_start (&dtp->common);
   4280   iolength_transfer_init (dtp);
   4281 }
   4282 
   4283 extern void st_iolength_done (st_parameter_dt *);
   4284 export_proto(st_iolength_done);
   4285 
   4286 void
   4287 st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
   4288 {
   4289   free_ionml (dtp);
   4290   library_end ();
   4291 }
   4292 
   4293 
   4294 /* The READ statement.  */
   4295 
   4296 extern void st_read (st_parameter_dt *);
   4297 export_proto(st_read);
   4298 
   4299 void
   4300 st_read (st_parameter_dt *dtp)
   4301 {
   4302   library_start (&dtp->common);
   4303 
   4304   data_transfer_init (dtp, 1);
   4305 }
   4306 
   4307 extern void st_read_done (st_parameter_dt *);
   4308 export_proto(st_read_done);
   4309 
   4310 void
   4311 st_read_done_worker (st_parameter_dt *dtp)
   4312 {
   4313   finalize_transfer (dtp);
   4314 
   4315   free_ionml (dtp);
   4316 
   4317   /* If this is a parent READ statement we do not need to retain the
   4318      internal unit structure for child use.  */
   4319   if (dtp->u.p.current_unit != NULL
   4320       && dtp->u.p.current_unit->child_dtio == 0)
   4321     {
   4322       if (dtp->u.p.unit_is_internal)
   4323 	{
   4324 	  if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
   4325 	    {
   4326 	      free (dtp->u.p.current_unit->filename);
   4327 	      dtp->u.p.current_unit->filename = NULL;
   4328 	      if (dtp->u.p.current_unit->ls)
   4329 		free (dtp->u.p.current_unit->ls);
   4330 	      dtp->u.p.current_unit->ls = NULL;
   4331 	    }
   4332 	  newunit_free (dtp->common.unit);
   4333 	}
   4334       if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
   4335 	{
   4336 	  free_format_data (dtp->u.p.fmt);
   4337 	  free_format (dtp);
   4338 	}
   4339     }
   4340 }
   4341 
   4342 void
   4343 st_read_done (st_parameter_dt *dtp)
   4344 {
   4345   if (dtp->u.p.current_unit)
   4346     {
   4347       if (dtp->u.p.current_unit->au)
   4348 	{
   4349 	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
   4350 	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);
   4351 	  else
   4352 	    {
   4353 	      if (dtp->u.p.async)
   4354 		enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
   4355 	    }
   4356 	}
   4357       else
   4358 	st_read_done_worker (dtp);
   4359 
   4360       unlock_unit (dtp->u.p.current_unit);
   4361     }
   4362 
   4363   library_end ();
   4364 }
   4365 
   4366 extern void st_write (st_parameter_dt *);
   4367 export_proto (st_write);
   4368 
   4369 void
   4370 st_write (st_parameter_dt *dtp)
   4371 {
   4372   library_start (&dtp->common);
   4373   data_transfer_init (dtp, 0);
   4374 }
   4375 
   4376 
   4377 void
   4378 st_write_done_worker (st_parameter_dt *dtp)
   4379 {
   4380   finalize_transfer (dtp);
   4381 
   4382   if (dtp->u.p.current_unit != NULL
   4383       && dtp->u.p.current_unit->child_dtio == 0)
   4384     {
   4385       /* Deal with endfile conditions associated with sequential files.  */
   4386       if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
   4387 	switch (dtp->u.p.current_unit->endfile)
   4388 	  {
   4389 	  case AT_ENDFILE:		/* Remain at the endfile record.  */
   4390 	    break;
   4391 
   4392 	  case AFTER_ENDFILE:
   4393 	    dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now.  */
   4394 	    break;
   4395 
   4396 	  case NO_ENDFILE:
   4397 	    /* Get rid of whatever is after this record.  */
   4398 	    if (!is_internal_unit (dtp))
   4399 	      unit_truncate (dtp->u.p.current_unit,
   4400 			     stell (dtp->u.p.current_unit->s),
   4401 			     &dtp->common);
   4402 	    dtp->u.p.current_unit->endfile = AT_ENDFILE;
   4403 	    break;
   4404 	  }
   4405 
   4406       free_ionml (dtp);
   4407 
   4408       /* If this is a parent WRITE statement we do not need to retain the
   4409 	 internal unit structure for child use.  */
   4410       if (dtp->u.p.unit_is_internal)
   4411 	{
   4412 	  if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
   4413 	    {
   4414 	      free (dtp->u.p.current_unit->filename);
   4415 	      dtp->u.p.current_unit->filename = NULL;
   4416 	      if (dtp->u.p.current_unit->ls)
   4417 		free (dtp->u.p.current_unit->ls);
   4418 	      dtp->u.p.current_unit->ls = NULL;
   4419 	    }
   4420 	  newunit_free (dtp->common.unit);
   4421 	}
   4422       if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
   4423 	{
   4424 	  free_format_data (dtp->u.p.fmt);
   4425 	  free_format (dtp);
   4426 	}
   4427     }
   4428 }
   4429 
   4430 extern void st_write_done (st_parameter_dt *);
   4431 export_proto(st_write_done);
   4432 
   4433 void
   4434 st_write_done (st_parameter_dt *dtp)
   4435 {
   4436   if (dtp->u.p.current_unit)
   4437     {
   4438       if (dtp->u.p.current_unit->au && dtp->u.p.async)
   4439 	{
   4440 	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
   4441 	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
   4442 					AIO_WRITE_DONE);
   4443 	  else
   4444 	    {
   4445 	      /* We perform synchronous I/O on an asynchronous unit, so no need
   4446 		 to enqueue AIO_READ_DONE.  */
   4447 	      if (dtp->u.p.async)
   4448 		enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
   4449 	    }
   4450 	}
   4451       else
   4452 	st_write_done_worker (dtp);
   4453 
   4454       unlock_unit (dtp->u.p.current_unit);
   4455     }
   4456 
   4457   library_end ();
   4458 }
   4459 
   4460 /* Wait operation.  We need to keep around the do-nothing version
   4461  of st_wait for compatibility with previous versions, which had marked
   4462  the argument as unused (and thus liable to be removed).
   4463 
   4464  TODO: remove at next bump in version number.  */
   4465 
   4466 void
   4467 st_wait (st_parameter_wait *wtp __attribute__((unused)))
   4468 {
   4469   return;
   4470 }
   4471 
   4472 void
   4473 st_wait_async (st_parameter_wait *wtp)
   4474 {
   4475   gfc_unit *u = find_unit (wtp->common.unit);
   4476   if (ASYNC_IO && u->au)
   4477     {
   4478       if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
   4479 	async_wait_id (&(wtp->common), u->au, *wtp->id);
   4480       else
   4481 	async_wait (&(wtp->common), u->au);
   4482     }
   4483 
   4484   unlock_unit (u);
   4485 }
   4486 
   4487 
   4488 /* Receives the scalar information for namelist objects and stores it
   4489    in a linked list of namelist_info types.  */
   4490 
   4491 static void
   4492 set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
   4493 	     GFC_INTEGER_4 len, gfc_charlen_type string_length,
   4494 	     dtype_type dtype, void *dtio_sub, void *vtable)
   4495 {
   4496   namelist_info *t1 = NULL;
   4497   namelist_info *nml;
   4498   size_t var_name_len = strlen (var_name);
   4499 
   4500   nml = (namelist_info*) xmalloc (sizeof (namelist_info));
   4501 
   4502   nml->mem_pos = var_addr;
   4503   nml->dtio_sub = dtio_sub;
   4504   nml->vtable = vtable;
   4505 
   4506   nml->var_name = (char*) xmalloc (var_name_len + 1);
   4507   memcpy (nml->var_name, var_name, var_name_len);
   4508   nml->var_name[var_name_len] = '\0';
   4509 
   4510   nml->len = (int) len;
   4511   nml->string_length = (index_type) string_length;
   4512 
   4513   nml->var_rank = (int) (dtype.rank);
   4514   nml->size = (index_type) (dtype.elem_len);
   4515   nml->type = (bt) (dtype.type);
   4516 
   4517   if (nml->var_rank > 0)
   4518     {
   4519       nml->dim = (descriptor_dimension*)
   4520 	xmallocarray (nml->var_rank, sizeof (descriptor_dimension));
   4521       nml->ls = (array_loop_spec*)
   4522 	xmallocarray (nml->var_rank, sizeof (array_loop_spec));
   4523     }
   4524   else
   4525     {
   4526       nml->dim = NULL;
   4527       nml->ls = NULL;
   4528     }
   4529 
   4530   nml->next = NULL;
   4531 
   4532   if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
   4533     {
   4534       dtp->common.flags |= IOPARM_DT_IONML_SET;
   4535       dtp->u.p.ionml = nml;
   4536     }
   4537   else
   4538     {
   4539       for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
   4540       t1->next = nml;
   4541     }
   4542 }
   4543 
   4544 extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
   4545 			    GFC_INTEGER_4, gfc_charlen_type, dtype_type);
   4546 export_proto(st_set_nml_var);
   4547 
   4548 void
   4549 st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
   4550 		GFC_INTEGER_4 len, gfc_charlen_type string_length,
   4551 		dtype_type dtype)
   4552 {
   4553   set_nml_var (dtp, var_addr, var_name, len, string_length,
   4554 	       dtype, NULL, NULL);
   4555 }
   4556 
   4557 
   4558 /* Essentially the same as previous but carrying the dtio procedure
   4559    and the vtable as additional arguments.  */
   4560 extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
   4561 				 GFC_INTEGER_4, gfc_charlen_type, dtype_type,
   4562 				 void *, void *);
   4563 export_proto(st_set_nml_dtio_var);
   4564 
   4565 
   4566 void
   4567 st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
   4568 		     GFC_INTEGER_4 len, gfc_charlen_type string_length,
   4569 		     dtype_type dtype, void *dtio_sub, void *vtable)
   4570 {
   4571   set_nml_var (dtp, var_addr, var_name, len, string_length,
   4572 	       dtype, dtio_sub, vtable);
   4573 }
   4574 
   4575 /* Store the dimensional information for the namelist object.  */
   4576 extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
   4577 				index_type, index_type,
   4578 				index_type);
   4579 export_proto(st_set_nml_var_dim);
   4580 
   4581 void
   4582 st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
   4583 		    index_type stride, index_type lbound,
   4584 		    index_type ubound)
   4585 {
   4586   namelist_info *nml;
   4587   int n;
   4588 
   4589   n = (int)n_dim;
   4590 
   4591   for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);
   4592 
   4593   GFC_DIMENSION_SET(nml->dim[n],lbound,ubound,stride);
   4594 }
   4595 
   4596 
   4597 /* Once upon a time, a poor innocent Fortran program was reading a
   4598    file, when suddenly it hit the end-of-file (EOF).  Unfortunately
   4599    the OS doesn't tell whether we're at the EOF or whether we already
   4600    went past it.  Luckily our hero, libgfortran, keeps track of this.
   4601    Call this function when you detect an EOF condition.  See Section
   4602    9.10.2 in F2003.  */
   4603 
   4604 void
   4605 hit_eof (st_parameter_dt *dtp)
   4606 {
   4607   dtp->u.p.current_unit->flags.position = POSITION_APPEND;
   4608 
   4609   if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
   4610     switch (dtp->u.p.current_unit->endfile)
   4611       {
   4612       case NO_ENDFILE:
   4613       case AT_ENDFILE:
   4614         generate_error (&dtp->common, LIBERROR_END, NULL);
   4615 	if (!is_internal_unit (dtp) && !dtp->u.p.namelist_mode)
   4616 	  {
   4617 	    dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
   4618 	    dtp->u.p.current_unit->current_record = 0;
   4619 	  }
   4620         else
   4621           dtp->u.p.current_unit->endfile = AT_ENDFILE;
   4622 	break;
   4623 
   4624       case AFTER_ENDFILE:
   4625 	generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
   4626 	dtp->u.p.current_unit->current_record = 0;
   4627 	break;
   4628       }
   4629   else
   4630     {
   4631       /* Non-sequential files don't have an ENDFILE record, so we
   4632          can't be at AFTER_ENDFILE.  */
   4633       dtp->u.p.current_unit->endfile = AT_ENDFILE;
   4634       generate_error (&dtp->common, LIBERROR_END, NULL);
   4635       dtp->u.p.current_unit->current_record = 0;
   4636     }
   4637 }
   4638