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