Home | History | Annotate | Line # | Download | only in io
transfer.c revision 1.1.1.2
      1  1.1.1.2  mrg /* Copyright (C) 2002-2020 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  mrg    opened with PAD=YES.  The caller must assume tailing 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  mrg   if (type == BT_CLASS)
   1092      1.1  mrg     {
   1093      1.1  mrg 	  int unit = dtp->u.p.current_unit->unit_number;
   1094      1.1  mrg 	  char tmp_iomsg[IOMSG_LEN] = "";
   1095      1.1  mrg 	  char *child_iomsg;
   1096      1.1  mrg 	  gfc_charlen_type child_iomsg_len;
   1097      1.1  mrg 	  int noiostat;
   1098      1.1  mrg 	  int *child_iostat = NULL;
   1099      1.1  mrg 
   1100      1.1  mrg 	  /* Set iostat, intent(out).  */
   1101      1.1  mrg 	  noiostat = 0;
   1102      1.1  mrg 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   1103      1.1  mrg 			  dtp->common.iostat : &noiostat;
   1104      1.1  mrg 
   1105      1.1  mrg 	  /* Set iomsg, intent(inout).  */
   1106      1.1  mrg 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   1107      1.1  mrg 	    {
   1108      1.1  mrg 	      child_iomsg = dtp->common.iomsg;
   1109      1.1  mrg 	      child_iomsg_len = dtp->common.iomsg_len;
   1110      1.1  mrg 	    }
   1111      1.1  mrg 	  else
   1112      1.1  mrg 	    {
   1113      1.1  mrg 	      child_iomsg = tmp_iomsg;
   1114      1.1  mrg 	      child_iomsg_len = IOMSG_LEN;
   1115      1.1  mrg 	    }
   1116      1.1  mrg 
   1117      1.1  mrg 	  /* Call the user defined unformatted READ procedure.  */
   1118      1.1  mrg 	  dtp->u.p.current_unit->child_dtio++;
   1119      1.1  mrg 	  dtp->u.p.ufdtio_ptr (dest, &unit, child_iostat, child_iomsg,
   1120      1.1  mrg 			      child_iomsg_len);
   1121      1.1  mrg 	  dtp->u.p.current_unit->child_dtio--;
   1122      1.1  mrg 	  return;
   1123      1.1  mrg     }
   1124      1.1  mrg 
   1125      1.1  mrg   if (type == BT_CHARACTER)
   1126      1.1  mrg     size *= GFC_SIZE_OF_CHAR_KIND(kind);
   1127      1.1  mrg   read_block_direct (dtp, dest, size * nelems);
   1128      1.1  mrg 
   1129      1.1  mrg   if (unlikely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_SWAP)
   1130      1.1  mrg       && kind != 1)
   1131      1.1  mrg     {
   1132      1.1  mrg       /* Handle wide chracters.  */
   1133      1.1  mrg       if (type == BT_CHARACTER)
   1134      1.1  mrg   	{
   1135      1.1  mrg   	  nelems *= size;
   1136      1.1  mrg   	  size = kind;
   1137      1.1  mrg   	}
   1138      1.1  mrg 
   1139      1.1  mrg       /* Break up complex into its constituent reals.  */
   1140      1.1  mrg       else if (type == BT_COMPLEX)
   1141      1.1  mrg   	{
   1142      1.1  mrg   	  nelems *= 2;
   1143      1.1  mrg   	  size /= 2;
   1144      1.1  mrg   	}
   1145      1.1  mrg       bswap_array (dest, dest, size, nelems);
   1146      1.1  mrg     }
   1147      1.1  mrg }
   1148      1.1  mrg 
   1149      1.1  mrg 
   1150      1.1  mrg /* Master function for unformatted writes.  NOTE: For kind=10 the size is 16
   1151      1.1  mrg    bytes on 64 bit machines.  The unused bytes are not initialized and never
   1152      1.1  mrg    used, which can show an error with memory checking analyzers like
   1153      1.1  mrg    valgrind.  We us BT_CLASS to denote a User Defined I/O call.  */
   1154      1.1  mrg 
   1155      1.1  mrg static void
   1156      1.1  mrg unformatted_write (st_parameter_dt *dtp, bt type,
   1157      1.1  mrg 		   void *source, int kind, size_t size, size_t nelems)
   1158      1.1  mrg {
   1159      1.1  mrg   if (type == BT_CLASS)
   1160      1.1  mrg     {
   1161      1.1  mrg 	  int unit = dtp->u.p.current_unit->unit_number;
   1162      1.1  mrg 	  char tmp_iomsg[IOMSG_LEN] = "";
   1163      1.1  mrg 	  char *child_iomsg;
   1164      1.1  mrg 	  gfc_charlen_type child_iomsg_len;
   1165      1.1  mrg 	  int noiostat;
   1166      1.1  mrg 	  int *child_iostat = NULL;
   1167      1.1  mrg 
   1168      1.1  mrg 	  /* Set iostat, intent(out).  */
   1169      1.1  mrg 	  noiostat = 0;
   1170      1.1  mrg 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   1171      1.1  mrg 			  dtp->common.iostat : &noiostat;
   1172      1.1  mrg 
   1173      1.1  mrg 	  /* Set iomsg, intent(inout).  */
   1174      1.1  mrg 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   1175      1.1  mrg 	    {
   1176      1.1  mrg 	      child_iomsg = dtp->common.iomsg;
   1177      1.1  mrg 	      child_iomsg_len = dtp->common.iomsg_len;
   1178      1.1  mrg 	    }
   1179      1.1  mrg 	  else
   1180      1.1  mrg 	    {
   1181      1.1  mrg 	      child_iomsg = tmp_iomsg;
   1182      1.1  mrg 	      child_iomsg_len = IOMSG_LEN;
   1183      1.1  mrg 	    }
   1184      1.1  mrg 
   1185      1.1  mrg 	  /* Call the user defined unformatted WRITE procedure.  */
   1186      1.1  mrg 	  dtp->u.p.current_unit->child_dtio++;
   1187      1.1  mrg 	  dtp->u.p.ufdtio_ptr (source, &unit, child_iostat, child_iomsg,
   1188      1.1  mrg 			      child_iomsg_len);
   1189      1.1  mrg 	  dtp->u.p.current_unit->child_dtio--;
   1190      1.1  mrg 	  return;
   1191      1.1  mrg     }
   1192      1.1  mrg 
   1193      1.1  mrg   if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
   1194      1.1  mrg       || kind == 1)
   1195      1.1  mrg     {
   1196      1.1  mrg       size_t stride = type == BT_CHARACTER ?
   1197      1.1  mrg 		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
   1198      1.1  mrg 
   1199      1.1  mrg       write_buf (dtp, source, stride * nelems);
   1200      1.1  mrg     }
   1201      1.1  mrg   else
   1202      1.1  mrg     {
   1203      1.1  mrg #define BSWAP_BUFSZ 512
   1204      1.1  mrg       char buffer[BSWAP_BUFSZ];
   1205      1.1  mrg       char *p;
   1206      1.1  mrg       size_t nrem;
   1207      1.1  mrg 
   1208      1.1  mrg       p = source;
   1209      1.1  mrg 
   1210      1.1  mrg       /* Handle wide chracters.  */
   1211      1.1  mrg       if (type == BT_CHARACTER && kind != 1)
   1212      1.1  mrg 	{
   1213      1.1  mrg 	  nelems *= size;
   1214      1.1  mrg 	  size = kind;
   1215      1.1  mrg 	}
   1216      1.1  mrg 
   1217      1.1  mrg       /* Break up complex into its constituent reals.  */
   1218      1.1  mrg       if (type == BT_COMPLEX)
   1219      1.1  mrg 	{
   1220      1.1  mrg 	  nelems *= 2;
   1221      1.1  mrg 	  size /= 2;
   1222      1.1  mrg 	}
   1223      1.1  mrg 
   1224      1.1  mrg       /* By now, all complex variables have been split into their
   1225      1.1  mrg 	 constituent reals.  */
   1226      1.1  mrg 
   1227      1.1  mrg       nrem = nelems;
   1228      1.1  mrg       do
   1229      1.1  mrg 	{
   1230      1.1  mrg 	  size_t nc;
   1231      1.1  mrg 	  if (size * nrem > BSWAP_BUFSZ)
   1232      1.1  mrg 	    nc = BSWAP_BUFSZ / size;
   1233      1.1  mrg 	  else
   1234      1.1  mrg 	    nc = nrem;
   1235      1.1  mrg 
   1236      1.1  mrg 	  bswap_array (buffer, p, size, nc);
   1237      1.1  mrg 	  write_buf (dtp, buffer, size * nc);
   1238      1.1  mrg 	  p += size * nc;
   1239      1.1  mrg 	  nrem -= nc;
   1240      1.1  mrg 	}
   1241      1.1  mrg       while (nrem > 0);
   1242      1.1  mrg     }
   1243      1.1  mrg }
   1244      1.1  mrg 
   1245      1.1  mrg 
   1246      1.1  mrg /* Return a pointer to the name of a type.  */
   1247      1.1  mrg 
   1248      1.1  mrg const char *
   1249      1.1  mrg type_name (bt type)
   1250      1.1  mrg {
   1251      1.1  mrg   const char *p;
   1252      1.1  mrg 
   1253      1.1  mrg   switch (type)
   1254      1.1  mrg     {
   1255      1.1  mrg     case BT_INTEGER:
   1256      1.1  mrg       p = "INTEGER";
   1257      1.1  mrg       break;
   1258      1.1  mrg     case BT_LOGICAL:
   1259      1.1  mrg       p = "LOGICAL";
   1260      1.1  mrg       break;
   1261      1.1  mrg     case BT_CHARACTER:
   1262      1.1  mrg       p = "CHARACTER";
   1263      1.1  mrg       break;
   1264      1.1  mrg     case BT_REAL:
   1265      1.1  mrg       p = "REAL";
   1266      1.1  mrg       break;
   1267      1.1  mrg     case BT_COMPLEX:
   1268      1.1  mrg       p = "COMPLEX";
   1269      1.1  mrg       break;
   1270      1.1  mrg     case BT_CLASS:
   1271      1.1  mrg       p = "CLASS or DERIVED";
   1272      1.1  mrg       break;
   1273      1.1  mrg     default:
   1274      1.1  mrg       internal_error (NULL, "type_name(): Bad type");
   1275      1.1  mrg     }
   1276      1.1  mrg 
   1277      1.1  mrg   return p;
   1278      1.1  mrg }
   1279      1.1  mrg 
   1280      1.1  mrg 
   1281      1.1  mrg /* Write a constant string to the output.
   1282      1.1  mrg    This is complicated because the string can have doubled delimiters
   1283      1.1  mrg    in it.  The length in the format node is the true length.  */
   1284      1.1  mrg 
   1285      1.1  mrg static void
   1286      1.1  mrg write_constant_string (st_parameter_dt *dtp, const fnode *f)
   1287      1.1  mrg {
   1288      1.1  mrg   char c, delimiter, *p, *q;
   1289      1.1  mrg   int length;
   1290      1.1  mrg 
   1291      1.1  mrg   length = f->u.string.length;
   1292      1.1  mrg   if (length == 0)
   1293      1.1  mrg     return;
   1294      1.1  mrg 
   1295      1.1  mrg   p = write_block (dtp, length);
   1296      1.1  mrg   if (p == NULL)
   1297      1.1  mrg     return;
   1298      1.1  mrg 
   1299      1.1  mrg   q = f->u.string.p;
   1300      1.1  mrg   delimiter = q[-1];
   1301      1.1  mrg 
   1302      1.1  mrg   for (; length > 0; length--)
   1303      1.1  mrg     {
   1304      1.1  mrg       c = *p++ = *q++;
   1305      1.1  mrg       if (c == delimiter && c != 'H' && c != 'h')
   1306      1.1  mrg 	q++;			/* Skip the doubled delimiter.  */
   1307      1.1  mrg     }
   1308      1.1  mrg }
   1309      1.1  mrg 
   1310      1.1  mrg 
   1311      1.1  mrg /* Given actual and expected types in a formatted data transfer, make
   1312      1.1  mrg    sure they agree.  If not, an error message is generated.  Returns
   1313      1.1  mrg    nonzero if something went wrong.  */
   1314      1.1  mrg 
   1315      1.1  mrg static int
   1316      1.1  mrg require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
   1317      1.1  mrg {
   1318      1.1  mrg #define BUFLEN 100
   1319      1.1  mrg   char buffer[BUFLEN];
   1320      1.1  mrg 
   1321      1.1  mrg   if (actual == expected)
   1322      1.1  mrg     return 0;
   1323      1.1  mrg 
   1324      1.1  mrg   /* Adjust item_count before emitting error message.  */
   1325      1.1  mrg   snprintf (buffer, BUFLEN,
   1326      1.1  mrg 	    "Expected %s for item %d in formatted transfer, got %s",
   1327      1.1  mrg 	   type_name (expected), dtp->u.p.item_count - 1, type_name (actual));
   1328      1.1  mrg 
   1329      1.1  mrg   format_error (dtp, f, buffer);
   1330      1.1  mrg   return 1;
   1331      1.1  mrg }
   1332      1.1  mrg 
   1333      1.1  mrg 
   1334      1.1  mrg /* Check that the dtio procedure required for formatted IO is present.  */
   1335      1.1  mrg 
   1336      1.1  mrg static int
   1337      1.1  mrg check_dtio_proc (st_parameter_dt *dtp, const fnode *f)
   1338      1.1  mrg {
   1339      1.1  mrg   char buffer[BUFLEN];
   1340      1.1  mrg 
   1341      1.1  mrg   if (dtp->u.p.fdtio_ptr != NULL)
   1342      1.1  mrg     return 0;
   1343      1.1  mrg 
   1344      1.1  mrg   snprintf (buffer, BUFLEN,
   1345      1.1  mrg 	    "Missing DTIO procedure or intrinsic type passed for item %d "
   1346      1.1  mrg 	    "in formatted transfer",
   1347      1.1  mrg 	    dtp->u.p.item_count - 1);
   1348      1.1  mrg 
   1349      1.1  mrg   format_error (dtp, f, buffer);
   1350      1.1  mrg   return 1;
   1351      1.1  mrg }
   1352      1.1  mrg 
   1353      1.1  mrg 
   1354      1.1  mrg static int
   1355      1.1  mrg require_numeric_type (st_parameter_dt *dtp, bt actual, const fnode *f)
   1356      1.1  mrg {
   1357      1.1  mrg #define BUFLEN 100
   1358      1.1  mrg   char buffer[BUFLEN];
   1359      1.1  mrg 
   1360      1.1  mrg   if (actual == BT_INTEGER || actual == BT_REAL || actual == BT_COMPLEX)
   1361      1.1  mrg     return 0;
   1362      1.1  mrg 
   1363      1.1  mrg   /* Adjust item_count before emitting error message.  */
   1364      1.1  mrg   snprintf (buffer, BUFLEN,
   1365      1.1  mrg 	    "Expected numeric type for item %d in formatted transfer, got %s",
   1366      1.1  mrg 	    dtp->u.p.item_count - 1, type_name (actual));
   1367      1.1  mrg 
   1368      1.1  mrg   format_error (dtp, f, buffer);
   1369      1.1  mrg   return 1;
   1370      1.1  mrg }
   1371      1.1  mrg 
   1372      1.1  mrg static char *
   1373      1.1  mrg get_dt_format (char *p, gfc_charlen_type *length)
   1374      1.1  mrg {
   1375      1.1  mrg   char delim = p[-1];  /* The delimiter is always the first character back.  */
   1376      1.1  mrg   char c, *q, *res;
   1377      1.1  mrg   gfc_charlen_type len = *length; /* This length already correct, less 'DT'.  */
   1378      1.1  mrg 
   1379      1.1  mrg   res = q = xmalloc (len + 2);
   1380      1.1  mrg 
   1381      1.1  mrg   /* Set the beginning of the string to 'DT', length adjusted below.  */
   1382      1.1  mrg   *q++ = 'D';
   1383      1.1  mrg   *q++ = 'T';
   1384      1.1  mrg 
   1385      1.1  mrg   /* The string may contain doubled quotes so scan and skip as needed.  */
   1386      1.1  mrg   for (; len > 0; len--)
   1387      1.1  mrg     {
   1388      1.1  mrg       c = *q++ = *p++;
   1389      1.1  mrg       if (c == delim)
   1390      1.1  mrg 	p++;  /* Skip the doubled delimiter.  */
   1391      1.1  mrg     }
   1392      1.1  mrg 
   1393      1.1  mrg   /* Adjust the string length by two now that we are done.  */
   1394      1.1  mrg   *length += 2;
   1395      1.1  mrg 
   1396      1.1  mrg   return res;
   1397      1.1  mrg }
   1398      1.1  mrg 
   1399      1.1  mrg 
   1400      1.1  mrg /* This function is in the main loop for a formatted data transfer
   1401      1.1  mrg    statement.  It would be natural to implement this as a coroutine
   1402      1.1  mrg    with the user program, but C makes that awkward.  We loop,
   1403      1.1  mrg    processing format elements.  When we actually have to transfer
   1404      1.1  mrg    data instead of just setting flags, we return control to the user
   1405      1.1  mrg    program which calls a function that supplies the address and type
   1406      1.1  mrg    of the next element, then comes back here to process it.  */
   1407      1.1  mrg 
   1408      1.1  mrg static void
   1409      1.1  mrg formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind,
   1410      1.1  mrg 				size_t size)
   1411      1.1  mrg {
   1412      1.1  mrg   int pos, bytes_used;
   1413      1.1  mrg   const fnode *f;
   1414      1.1  mrg   format_token t;
   1415      1.1  mrg   int n;
   1416      1.1  mrg   int consume_data_flag;
   1417      1.1  mrg 
   1418      1.1  mrg   /* Change a complex data item into a pair of reals.  */
   1419      1.1  mrg 
   1420      1.1  mrg   n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
   1421      1.1  mrg   if (type == BT_COMPLEX)
   1422      1.1  mrg     {
   1423      1.1  mrg       type = BT_REAL;
   1424      1.1  mrg       size /= 2;
   1425      1.1  mrg     }
   1426      1.1  mrg 
   1427      1.1  mrg   /* If there's an EOR condition, we simulate finalizing the transfer
   1428      1.1  mrg      by doing nothing.  */
   1429      1.1  mrg   if (dtp->u.p.eor_condition)
   1430      1.1  mrg     return;
   1431      1.1  mrg 
   1432      1.1  mrg   /* Set this flag so that commas in reads cause the read to complete before
   1433      1.1  mrg      the entire field has been read.  The next read field will start right after
   1434      1.1  mrg      the comma in the stream.  (Set to 0 for character reads).  */
   1435      1.1  mrg   dtp->u.p.sf_read_comma =
   1436      1.1  mrg     dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
   1437      1.1  mrg 
   1438      1.1  mrg   for (;;)
   1439      1.1  mrg     {
   1440      1.1  mrg       /* If reversion has occurred and there is another real data item,
   1441      1.1  mrg 	 then we have to move to the next record.  */
   1442      1.1  mrg       if (dtp->u.p.reversion_flag && n > 0)
   1443      1.1  mrg 	{
   1444      1.1  mrg 	  dtp->u.p.reversion_flag = 0;
   1445      1.1  mrg 	  next_record (dtp, 0);
   1446      1.1  mrg 	}
   1447      1.1  mrg 
   1448      1.1  mrg       consume_data_flag = 1;
   1449      1.1  mrg       if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   1450      1.1  mrg 	break;
   1451      1.1  mrg 
   1452      1.1  mrg       f = next_format (dtp);
   1453      1.1  mrg       if (f == NULL)
   1454      1.1  mrg 	{
   1455      1.1  mrg 	  /* No data descriptors left.  */
   1456      1.1  mrg 	  if (unlikely (n > 0))
   1457      1.1  mrg 	    generate_error (&dtp->common, LIBERROR_FORMAT,
   1458      1.1  mrg 		"Insufficient data descriptors in format after reversion");
   1459      1.1  mrg 	  return;
   1460      1.1  mrg 	}
   1461      1.1  mrg 
   1462      1.1  mrg       t = f->format;
   1463      1.1  mrg 
   1464      1.1  mrg       bytes_used = (int)(dtp->u.p.current_unit->recl
   1465      1.1  mrg 		   - dtp->u.p.current_unit->bytes_left);
   1466      1.1  mrg 
   1467      1.1  mrg       if (is_stream_io(dtp))
   1468      1.1  mrg 	bytes_used = 0;
   1469      1.1  mrg 
   1470      1.1  mrg       switch (t)
   1471      1.1  mrg 	{
   1472      1.1  mrg 	case FMT_I:
   1473      1.1  mrg 	  if (n == 0)
   1474      1.1  mrg 	    goto need_read_data;
   1475      1.1  mrg 	  if (require_type (dtp, BT_INTEGER, type, f))
   1476      1.1  mrg 	    return;
   1477      1.1  mrg 	  read_decimal (dtp, f, p, kind);
   1478      1.1  mrg 	  break;
   1479      1.1  mrg 
   1480      1.1  mrg 	case FMT_B:
   1481      1.1  mrg 	  if (n == 0)
   1482      1.1  mrg 	    goto need_read_data;
   1483      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1484      1.1  mrg 	      && require_numeric_type (dtp, type, f))
   1485      1.1  mrg 	    return;
   1486      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1487      1.1  mrg               && require_type (dtp, BT_INTEGER, type, f))
   1488      1.1  mrg 	    return;
   1489      1.1  mrg 	  read_radix (dtp, f, p, kind, 2);
   1490      1.1  mrg 	  break;
   1491      1.1  mrg 
   1492      1.1  mrg 	case FMT_O:
   1493      1.1  mrg 	  if (n == 0)
   1494      1.1  mrg 	    goto need_read_data;
   1495      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1496      1.1  mrg 	      && require_numeric_type (dtp, type, f))
   1497      1.1  mrg 	    return;
   1498      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1499      1.1  mrg               && require_type (dtp, BT_INTEGER, type, f))
   1500      1.1  mrg 	    return;
   1501      1.1  mrg 	  read_radix (dtp, f, p, kind, 8);
   1502      1.1  mrg 	  break;
   1503      1.1  mrg 
   1504      1.1  mrg 	case FMT_Z:
   1505      1.1  mrg 	  if (n == 0)
   1506      1.1  mrg 	    goto need_read_data;
   1507      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1508      1.1  mrg 	      && require_numeric_type (dtp, type, f))
   1509      1.1  mrg 	    return;
   1510      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1511      1.1  mrg               && require_type (dtp, BT_INTEGER, type, f))
   1512      1.1  mrg 	    return;
   1513      1.1  mrg 	  read_radix (dtp, f, p, kind, 16);
   1514      1.1  mrg 	  break;
   1515      1.1  mrg 
   1516      1.1  mrg 	case FMT_A:
   1517      1.1  mrg 	  if (n == 0)
   1518      1.1  mrg 	    goto need_read_data;
   1519      1.1  mrg 
   1520      1.1  mrg 	  /* It is possible to have FMT_A with something not BT_CHARACTER such
   1521      1.1  mrg 	     as when writing out hollerith strings, so check both type
   1522      1.1  mrg 	     and kind before calling wide character routines.  */
   1523      1.1  mrg 	  if (type == BT_CHARACTER && kind == 4)
   1524      1.1  mrg 	    read_a_char4 (dtp, f, p, size);
   1525      1.1  mrg 	  else
   1526      1.1  mrg 	    read_a (dtp, f, p, size);
   1527      1.1  mrg 	  break;
   1528      1.1  mrg 
   1529      1.1  mrg 	case FMT_L:
   1530      1.1  mrg 	  if (n == 0)
   1531      1.1  mrg 	    goto need_read_data;
   1532      1.1  mrg 	  read_l (dtp, f, p, kind);
   1533      1.1  mrg 	  break;
   1534      1.1  mrg 
   1535      1.1  mrg 	case FMT_D:
   1536      1.1  mrg 	  if (n == 0)
   1537      1.1  mrg 	    goto need_read_data;
   1538      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   1539      1.1  mrg 	    return;
   1540      1.1  mrg 	  read_f (dtp, f, p, kind);
   1541      1.1  mrg 	  break;
   1542      1.1  mrg 
   1543      1.1  mrg 	case FMT_DT:
   1544      1.1  mrg 	  if (n == 0)
   1545      1.1  mrg 	    goto need_read_data;
   1546      1.1  mrg 
   1547      1.1  mrg 	  if (check_dtio_proc (dtp, f))
   1548      1.1  mrg 	    return;
   1549      1.1  mrg 	  if (require_type (dtp, BT_CLASS, type, f))
   1550      1.1  mrg 	    return;
   1551      1.1  mrg 	  int unit = dtp->u.p.current_unit->unit_number;
   1552      1.1  mrg 	  char dt[] = "DT";
   1553      1.1  mrg 	  char tmp_iomsg[IOMSG_LEN] = "";
   1554      1.1  mrg 	  char *child_iomsg;
   1555      1.1  mrg 	  gfc_charlen_type child_iomsg_len;
   1556      1.1  mrg 	  int noiostat;
   1557      1.1  mrg 	  int *child_iostat = NULL;
   1558      1.1  mrg 	  char *iotype;
   1559      1.1  mrg 	  gfc_charlen_type iotype_len = f->u.udf.string_len;
   1560      1.1  mrg 
   1561      1.1  mrg 	  /* Build the iotype string.  */
   1562      1.1  mrg 	  if (iotype_len == 0)
   1563      1.1  mrg 	    {
   1564      1.1  mrg 	      iotype_len = 2;
   1565      1.1  mrg 	      iotype = dt;
   1566      1.1  mrg 	    }
   1567      1.1  mrg 	  else
   1568      1.1  mrg 	    iotype = get_dt_format (f->u.udf.string, &iotype_len);
   1569      1.1  mrg 
   1570      1.1  mrg 	  /* Set iostat, intent(out).  */
   1571      1.1  mrg 	  noiostat = 0;
   1572      1.1  mrg 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   1573      1.1  mrg 			  dtp->common.iostat : &noiostat;
   1574      1.1  mrg 
   1575      1.1  mrg 	  /* Set iomsg, intent(inout).  */
   1576      1.1  mrg 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   1577      1.1  mrg 	    {
   1578      1.1  mrg 	      child_iomsg = dtp->common.iomsg;
   1579      1.1  mrg 	      child_iomsg_len = dtp->common.iomsg_len;
   1580      1.1  mrg 	    }
   1581      1.1  mrg 	  else
   1582      1.1  mrg 	    {
   1583      1.1  mrg 	      child_iomsg = tmp_iomsg;
   1584      1.1  mrg 	      child_iomsg_len = IOMSG_LEN;
   1585      1.1  mrg 	    }
   1586      1.1  mrg 
   1587      1.1  mrg 	  /* Call the user defined formatted READ procedure.  */
   1588      1.1  mrg 	  dtp->u.p.current_unit->child_dtio++;
   1589      1.1  mrg 	  dtp->u.p.current_unit->last_char = EOF - 1;
   1590      1.1  mrg 	  dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
   1591      1.1  mrg 			      child_iostat, child_iomsg,
   1592      1.1  mrg 			      iotype_len, child_iomsg_len);
   1593      1.1  mrg 	  dtp->u.p.current_unit->child_dtio--;
   1594      1.1  mrg 
   1595      1.1  mrg 	  if (f->u.udf.string_len != 0)
   1596      1.1  mrg 	    free (iotype);
   1597      1.1  mrg 	  /* Note: vlist is freed in free_format_data.  */
   1598      1.1  mrg 	  break;
   1599      1.1  mrg 
   1600      1.1  mrg 	case FMT_E:
   1601      1.1  mrg 	  if (n == 0)
   1602      1.1  mrg 	    goto need_read_data;
   1603      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   1604      1.1  mrg 	    return;
   1605      1.1  mrg 	  read_f (dtp, f, p, kind);
   1606      1.1  mrg 	  break;
   1607      1.1  mrg 
   1608      1.1  mrg 	case FMT_EN:
   1609      1.1  mrg 	  if (n == 0)
   1610      1.1  mrg 	    goto need_read_data;
   1611      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   1612      1.1  mrg 	    return;
   1613      1.1  mrg 	  read_f (dtp, f, p, kind);
   1614      1.1  mrg 	  break;
   1615      1.1  mrg 
   1616      1.1  mrg 	case FMT_ES:
   1617      1.1  mrg 	  if (n == 0)
   1618      1.1  mrg 	    goto need_read_data;
   1619      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   1620      1.1  mrg 	    return;
   1621      1.1  mrg 	  read_f (dtp, f, p, kind);
   1622      1.1  mrg 	  break;
   1623      1.1  mrg 
   1624      1.1  mrg 	case FMT_F:
   1625      1.1  mrg 	  if (n == 0)
   1626      1.1  mrg 	    goto need_read_data;
   1627      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   1628      1.1  mrg 	    return;
   1629      1.1  mrg 	  read_f (dtp, f, p, kind);
   1630      1.1  mrg 	  break;
   1631      1.1  mrg 
   1632      1.1  mrg 	case FMT_G:
   1633      1.1  mrg 	  if (n == 0)
   1634      1.1  mrg 	    goto need_read_data;
   1635      1.1  mrg 	  switch (type)
   1636      1.1  mrg 	    {
   1637      1.1  mrg 	      case BT_INTEGER:
   1638      1.1  mrg 		read_decimal (dtp, f, p, kind);
   1639      1.1  mrg 		break;
   1640      1.1  mrg 	      case BT_LOGICAL:
   1641      1.1  mrg 		read_l (dtp, f, p, kind);
   1642      1.1  mrg 		break;
   1643      1.1  mrg 	      case BT_CHARACTER:
   1644      1.1  mrg 		if (kind == 4)
   1645      1.1  mrg 		  read_a_char4 (dtp, f, p, size);
   1646      1.1  mrg 		else
   1647      1.1  mrg 		  read_a (dtp, f, p, size);
   1648      1.1  mrg 		break;
   1649      1.1  mrg 	      case BT_REAL:
   1650      1.1  mrg 		read_f (dtp, f, p, kind);
   1651      1.1  mrg 		break;
   1652      1.1  mrg 	      default:
   1653      1.1  mrg 		internal_error (&dtp->common,
   1654      1.1  mrg 				"formatted_transfer (): Bad type");
   1655      1.1  mrg 	    }
   1656      1.1  mrg 	  break;
   1657      1.1  mrg 
   1658      1.1  mrg 	case FMT_STRING:
   1659      1.1  mrg 	  consume_data_flag = 0;
   1660      1.1  mrg 	  format_error (dtp, f, "Constant string in input format");
   1661      1.1  mrg 	  return;
   1662      1.1  mrg 
   1663      1.1  mrg 	/* Format codes that don't transfer data.  */
   1664      1.1  mrg 	case FMT_X:
   1665      1.1  mrg 	case FMT_TR:
   1666      1.1  mrg 	  consume_data_flag = 0;
   1667      1.1  mrg 	  dtp->u.p.skips += f->u.n;
   1668      1.1  mrg 	  pos = bytes_used + dtp->u.p.skips - 1;
   1669      1.1  mrg 	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
   1670      1.1  mrg 	  read_x (dtp, f->u.n);
   1671      1.1  mrg 	  break;
   1672      1.1  mrg 
   1673      1.1  mrg 	case FMT_TL:
   1674      1.1  mrg 	case FMT_T:
   1675      1.1  mrg 	  consume_data_flag = 0;
   1676      1.1  mrg 
   1677      1.1  mrg 	  if (f->format == FMT_TL)
   1678      1.1  mrg 	    {
   1679      1.1  mrg 	      /* Handle the special case when no bytes have been used yet.
   1680      1.1  mrg 	         Cannot go below zero. */
   1681      1.1  mrg 	      if (bytes_used == 0)
   1682      1.1  mrg 		{
   1683      1.1  mrg 		  dtp->u.p.pending_spaces -= f->u.n;
   1684      1.1  mrg 		  dtp->u.p.skips -= f->u.n;
   1685      1.1  mrg 		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
   1686      1.1  mrg 		}
   1687      1.1  mrg 
   1688      1.1  mrg 	      pos = bytes_used - f->u.n;
   1689      1.1  mrg 	    }
   1690      1.1  mrg 	  else /* FMT_T */
   1691      1.1  mrg 	    pos = f->u.n - 1;
   1692      1.1  mrg 
   1693      1.1  mrg 	  /* Standard 10.6.1.1: excessive left tabbing is reset to the
   1694      1.1  mrg 	     left tab limit.  We do not check if the position has gone
   1695      1.1  mrg 	     beyond the end of record because a subsequent tab could
   1696      1.1  mrg 	     bring us back again.  */
   1697      1.1  mrg 	  pos = pos < 0 ? 0 : pos;
   1698      1.1  mrg 
   1699      1.1  mrg 	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
   1700      1.1  mrg 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
   1701      1.1  mrg 				    + pos - dtp->u.p.max_pos;
   1702      1.1  mrg 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
   1703      1.1  mrg 				    ? 0 : dtp->u.p.pending_spaces;
   1704      1.1  mrg 	  if (dtp->u.p.skips == 0)
   1705      1.1  mrg 	    break;
   1706      1.1  mrg 
   1707      1.1  mrg 	  /* Adjust everything for end-of-record condition */
   1708      1.1  mrg 	  if (dtp->u.p.sf_seen_eor && !is_internal_unit (dtp))
   1709      1.1  mrg 	    {
   1710      1.1  mrg               dtp->u.p.current_unit->bytes_left -= dtp->u.p.sf_seen_eor;
   1711      1.1  mrg               dtp->u.p.skips -= dtp->u.p.sf_seen_eor;
   1712      1.1  mrg 	      bytes_used = pos;
   1713      1.1  mrg 	      if (dtp->u.p.pending_spaces == 0)
   1714      1.1  mrg 		dtp->u.p.sf_seen_eor = 0;
   1715      1.1  mrg 	    }
   1716      1.1  mrg 	  if (dtp->u.p.skips < 0)
   1717      1.1  mrg 	    {
   1718      1.1  mrg               if (is_internal_unit (dtp))
   1719      1.1  mrg                 sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
   1720      1.1  mrg               else
   1721      1.1  mrg                 fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
   1722      1.1  mrg 	      dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
   1723      1.1  mrg 	      dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   1724      1.1  mrg 	    }
   1725      1.1  mrg 	  else
   1726      1.1  mrg 	    read_x (dtp, dtp->u.p.skips);
   1727      1.1  mrg 	  break;
   1728      1.1  mrg 
   1729      1.1  mrg 	case FMT_S:
   1730      1.1  mrg 	  consume_data_flag = 0;
   1731  1.1.1.2  mrg 	  dtp->u.p.sign_status = SIGN_PROCDEFINED;
   1732      1.1  mrg 	  break;
   1733      1.1  mrg 
   1734      1.1  mrg 	case FMT_SS:
   1735      1.1  mrg 	  consume_data_flag = 0;
   1736  1.1.1.2  mrg 	  dtp->u.p.sign_status = SIGN_SUPPRESS;
   1737      1.1  mrg 	  break;
   1738      1.1  mrg 
   1739      1.1  mrg 	case FMT_SP:
   1740      1.1  mrg 	  consume_data_flag = 0;
   1741  1.1.1.2  mrg 	  dtp->u.p.sign_status = SIGN_PLUS;
   1742      1.1  mrg 	  break;
   1743      1.1  mrg 
   1744      1.1  mrg 	case FMT_BN:
   1745      1.1  mrg 	  consume_data_flag = 0 ;
   1746      1.1  mrg 	  dtp->u.p.blank_status = BLANK_NULL;
   1747      1.1  mrg 	  break;
   1748      1.1  mrg 
   1749      1.1  mrg 	case FMT_BZ:
   1750      1.1  mrg 	  consume_data_flag = 0;
   1751      1.1  mrg 	  dtp->u.p.blank_status = BLANK_ZERO;
   1752      1.1  mrg 	  break;
   1753      1.1  mrg 
   1754      1.1  mrg 	case FMT_DC:
   1755      1.1  mrg 	  consume_data_flag = 0;
   1756      1.1  mrg 	  dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
   1757      1.1  mrg 	  break;
   1758      1.1  mrg 
   1759      1.1  mrg 	case FMT_DP:
   1760      1.1  mrg 	  consume_data_flag = 0;
   1761      1.1  mrg 	  dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
   1762      1.1  mrg 	  break;
   1763      1.1  mrg 
   1764      1.1  mrg 	case FMT_RC:
   1765      1.1  mrg 	  consume_data_flag = 0;
   1766      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
   1767      1.1  mrg 	  break;
   1768      1.1  mrg 
   1769      1.1  mrg 	case FMT_RD:
   1770      1.1  mrg 	  consume_data_flag = 0;
   1771      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_DOWN;
   1772      1.1  mrg 	  break;
   1773      1.1  mrg 
   1774      1.1  mrg 	case FMT_RN:
   1775      1.1  mrg 	  consume_data_flag = 0;
   1776      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_NEAREST;
   1777      1.1  mrg 	  break;
   1778      1.1  mrg 
   1779      1.1  mrg 	case FMT_RP:
   1780      1.1  mrg 	  consume_data_flag = 0;
   1781      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
   1782      1.1  mrg 	  break;
   1783      1.1  mrg 
   1784      1.1  mrg 	case FMT_RU:
   1785      1.1  mrg 	  consume_data_flag = 0;
   1786      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_UP;
   1787      1.1  mrg 	  break;
   1788      1.1  mrg 
   1789      1.1  mrg 	case FMT_RZ:
   1790      1.1  mrg 	  consume_data_flag = 0;
   1791      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_ZERO;
   1792      1.1  mrg 	  break;
   1793      1.1  mrg 
   1794      1.1  mrg 	case FMT_P:
   1795      1.1  mrg 	  consume_data_flag = 0;
   1796      1.1  mrg 	  dtp->u.p.scale_factor = f->u.k;
   1797      1.1  mrg 	  break;
   1798      1.1  mrg 
   1799      1.1  mrg 	case FMT_DOLLAR:
   1800      1.1  mrg 	  consume_data_flag = 0;
   1801      1.1  mrg 	  dtp->u.p.seen_dollar = 1;
   1802      1.1  mrg 	  break;
   1803      1.1  mrg 
   1804      1.1  mrg 	case FMT_SLASH:
   1805      1.1  mrg 	  consume_data_flag = 0;
   1806      1.1  mrg 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   1807      1.1  mrg 	  next_record (dtp, 0);
   1808      1.1  mrg 	  break;
   1809      1.1  mrg 
   1810      1.1  mrg 	case FMT_COLON:
   1811      1.1  mrg 	  /* A colon descriptor causes us to exit this loop (in
   1812      1.1  mrg 	     particular preventing another / descriptor from being
   1813      1.1  mrg 	     processed) unless there is another data item to be
   1814      1.1  mrg 	     transferred.  */
   1815      1.1  mrg 	  consume_data_flag = 0;
   1816      1.1  mrg 	  if (n == 0)
   1817      1.1  mrg 	    return;
   1818      1.1  mrg 	  break;
   1819      1.1  mrg 
   1820      1.1  mrg 	default:
   1821      1.1  mrg 	  internal_error (&dtp->common, "Bad format node");
   1822      1.1  mrg 	}
   1823      1.1  mrg 
   1824      1.1  mrg       /* Adjust the item count and data pointer.  */
   1825      1.1  mrg 
   1826      1.1  mrg       if ((consume_data_flag > 0) && (n > 0))
   1827      1.1  mrg 	{
   1828      1.1  mrg 	  n--;
   1829      1.1  mrg 	  p = ((char *) p) + size;
   1830      1.1  mrg 	}
   1831      1.1  mrg 
   1832      1.1  mrg       dtp->u.p.skips = 0;
   1833      1.1  mrg 
   1834      1.1  mrg       pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
   1835      1.1  mrg       dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
   1836      1.1  mrg     }
   1837      1.1  mrg 
   1838      1.1  mrg   return;
   1839      1.1  mrg 
   1840      1.1  mrg   /* Come here when we need a data descriptor but don't have one.  We
   1841      1.1  mrg      push the current format node back onto the input, then return and
   1842      1.1  mrg      let the user program call us back with the data.  */
   1843      1.1  mrg  need_read_data:
   1844      1.1  mrg   unget_format (dtp, f);
   1845      1.1  mrg }
   1846      1.1  mrg 
   1847      1.1  mrg 
   1848      1.1  mrg static void
   1849      1.1  mrg formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind,
   1850      1.1  mrg 				 size_t size)
   1851      1.1  mrg {
   1852      1.1  mrg   gfc_offset pos, bytes_used;
   1853      1.1  mrg   const fnode *f;
   1854      1.1  mrg   format_token t;
   1855      1.1  mrg   int n;
   1856      1.1  mrg   int consume_data_flag;
   1857      1.1  mrg 
   1858      1.1  mrg   /* Change a complex data item into a pair of reals.  */
   1859      1.1  mrg 
   1860      1.1  mrg   n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
   1861      1.1  mrg   if (type == BT_COMPLEX)
   1862      1.1  mrg     {
   1863      1.1  mrg       type = BT_REAL;
   1864      1.1  mrg       size /= 2;
   1865      1.1  mrg     }
   1866      1.1  mrg 
   1867      1.1  mrg   /* If there's an EOR condition, we simulate finalizing the transfer
   1868      1.1  mrg      by doing nothing.  */
   1869      1.1  mrg   if (dtp->u.p.eor_condition)
   1870      1.1  mrg     return;
   1871      1.1  mrg 
   1872      1.1  mrg   /* Set this flag so that commas in reads cause the read to complete before
   1873      1.1  mrg      the entire field has been read.  The next read field will start right after
   1874      1.1  mrg      the comma in the stream.  (Set to 0 for character reads).  */
   1875      1.1  mrg   dtp->u.p.sf_read_comma =
   1876      1.1  mrg     dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
   1877      1.1  mrg 
   1878      1.1  mrg   for (;;)
   1879      1.1  mrg     {
   1880      1.1  mrg       /* If reversion has occurred and there is another real data item,
   1881      1.1  mrg 	 then we have to move to the next record.  */
   1882      1.1  mrg       if (dtp->u.p.reversion_flag && n > 0)
   1883      1.1  mrg 	{
   1884      1.1  mrg 	  dtp->u.p.reversion_flag = 0;
   1885      1.1  mrg 	  next_record (dtp, 0);
   1886      1.1  mrg 	}
   1887      1.1  mrg 
   1888      1.1  mrg       consume_data_flag = 1;
   1889      1.1  mrg       if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   1890      1.1  mrg 	break;
   1891      1.1  mrg 
   1892      1.1  mrg       f = next_format (dtp);
   1893      1.1  mrg       if (f == NULL)
   1894      1.1  mrg 	{
   1895      1.1  mrg 	  /* No data descriptors left.  */
   1896      1.1  mrg 	  if (unlikely (n > 0))
   1897      1.1  mrg 	    generate_error (&dtp->common, LIBERROR_FORMAT,
   1898      1.1  mrg 		"Insufficient data descriptors in format after reversion");
   1899      1.1  mrg 	  return;
   1900      1.1  mrg 	}
   1901      1.1  mrg 
   1902      1.1  mrg       /* Now discharge T, TR and X movements to the right.  This is delayed
   1903      1.1  mrg 	 until a data producing format to suppress trailing spaces.  */
   1904      1.1  mrg 
   1905      1.1  mrg       t = f->format;
   1906      1.1  mrg       if (dtp->u.p.mode == WRITING && dtp->u.p.skips != 0
   1907      1.1  mrg 	&& ((n>0 && (  t == FMT_I  || t == FMT_B  || t == FMT_O
   1908      1.1  mrg 		    || t == FMT_Z  || t == FMT_F  || t == FMT_E
   1909      1.1  mrg 		    || t == FMT_EN || t == FMT_ES || t == FMT_G
   1910      1.1  mrg 		    || t == FMT_L  || t == FMT_A  || t == FMT_D
   1911      1.1  mrg 		    || t == FMT_DT))
   1912      1.1  mrg 	    || t == FMT_STRING))
   1913      1.1  mrg 	{
   1914      1.1  mrg 	  if (dtp->u.p.skips > 0)
   1915      1.1  mrg 	    {
   1916      1.1  mrg 	      gfc_offset tmp;
   1917      1.1  mrg 	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
   1918      1.1  mrg 	      tmp = dtp->u.p.current_unit->recl
   1919      1.1  mrg 			  - dtp->u.p.current_unit->bytes_left;
   1920      1.1  mrg 	      dtp->u.p.max_pos =
   1921      1.1  mrg 		dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
   1922      1.1  mrg 	      dtp->u.p.skips = 0;
   1923      1.1  mrg 	    }
   1924      1.1  mrg 	  if (dtp->u.p.skips < 0)
   1925      1.1  mrg 	    {
   1926      1.1  mrg               if (is_internal_unit (dtp))
   1927      1.1  mrg 	        sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
   1928      1.1  mrg               else
   1929      1.1  mrg                 fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
   1930      1.1  mrg 	      dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
   1931      1.1  mrg 	    }
   1932      1.1  mrg 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   1933      1.1  mrg 	}
   1934      1.1  mrg 
   1935      1.1  mrg       bytes_used = dtp->u.p.current_unit->recl
   1936      1.1  mrg 		   - dtp->u.p.current_unit->bytes_left;
   1937      1.1  mrg 
   1938      1.1  mrg       if (is_stream_io(dtp))
   1939      1.1  mrg 	bytes_used = 0;
   1940      1.1  mrg 
   1941      1.1  mrg       switch (t)
   1942      1.1  mrg 	{
   1943      1.1  mrg 	case FMT_I:
   1944      1.1  mrg 	  if (n == 0)
   1945      1.1  mrg 	    goto need_data;
   1946      1.1  mrg 	  if (require_type (dtp, BT_INTEGER, type, f))
   1947      1.1  mrg 	    return;
   1948      1.1  mrg 	  write_i (dtp, f, p, kind);
   1949      1.1  mrg 	  break;
   1950      1.1  mrg 
   1951      1.1  mrg 	case FMT_B:
   1952      1.1  mrg 	  if (n == 0)
   1953      1.1  mrg 	    goto need_data;
   1954      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1955      1.1  mrg 	      && require_numeric_type (dtp, type, f))
   1956      1.1  mrg 	    return;
   1957      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1958      1.1  mrg               && require_type (dtp, BT_INTEGER, type, f))
   1959      1.1  mrg 	    return;
   1960      1.1  mrg 	  write_b (dtp, f, p, kind);
   1961      1.1  mrg 	  break;
   1962      1.1  mrg 
   1963      1.1  mrg 	case FMT_O:
   1964      1.1  mrg 	  if (n == 0)
   1965      1.1  mrg 	    goto need_data;
   1966      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1967      1.1  mrg 	      && require_numeric_type (dtp, type, f))
   1968      1.1  mrg 	    return;
   1969      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1970      1.1  mrg               && require_type (dtp, BT_INTEGER, type, f))
   1971      1.1  mrg 	    return;
   1972      1.1  mrg 	  write_o (dtp, f, p, kind);
   1973      1.1  mrg 	  break;
   1974      1.1  mrg 
   1975      1.1  mrg 	case FMT_Z:
   1976      1.1  mrg 	  if (n == 0)
   1977      1.1  mrg 	    goto need_data;
   1978      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_GNU)
   1979      1.1  mrg 	      && require_numeric_type (dtp, type, f))
   1980      1.1  mrg 	    return;
   1981      1.1  mrg 	  if (!(compile_options.allow_std & GFC_STD_F2008)
   1982      1.1  mrg               && require_type (dtp, BT_INTEGER, type, f))
   1983      1.1  mrg 	    return;
   1984      1.1  mrg 	  write_z (dtp, f, p, kind);
   1985      1.1  mrg 	  break;
   1986      1.1  mrg 
   1987      1.1  mrg 	case FMT_A:
   1988      1.1  mrg 	  if (n == 0)
   1989      1.1  mrg 	    goto need_data;
   1990      1.1  mrg 
   1991      1.1  mrg 	  /* It is possible to have FMT_A with something not BT_CHARACTER such
   1992      1.1  mrg 	     as when writing out hollerith strings, so check both type
   1993      1.1  mrg 	     and kind before calling wide character routines.  */
   1994      1.1  mrg 	  if (type == BT_CHARACTER && kind == 4)
   1995      1.1  mrg 	    write_a_char4 (dtp, f, p, size);
   1996      1.1  mrg 	  else
   1997      1.1  mrg 	    write_a (dtp, f, p, size);
   1998      1.1  mrg 	  break;
   1999      1.1  mrg 
   2000      1.1  mrg 	case FMT_L:
   2001      1.1  mrg 	  if (n == 0)
   2002      1.1  mrg 	    goto need_data;
   2003      1.1  mrg 	  write_l (dtp, f, p, kind);
   2004      1.1  mrg 	  break;
   2005      1.1  mrg 
   2006      1.1  mrg 	case FMT_D:
   2007      1.1  mrg 	  if (n == 0)
   2008      1.1  mrg 	    goto need_data;
   2009      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   2010      1.1  mrg 	    return;
   2011  1.1.1.2  mrg 	  if (f->u.real.w == 0)
   2012  1.1.1.2  mrg 	    write_real_w0 (dtp, p, kind, f);
   2013  1.1.1.2  mrg 	  else
   2014  1.1.1.2  mrg 	    write_d (dtp, f, p, kind);
   2015      1.1  mrg 	  break;
   2016      1.1  mrg 
   2017      1.1  mrg 	case FMT_DT:
   2018      1.1  mrg 	  if (n == 0)
   2019      1.1  mrg 	    goto need_data;
   2020      1.1  mrg 	  int unit = dtp->u.p.current_unit->unit_number;
   2021      1.1  mrg 	  char dt[] = "DT";
   2022      1.1  mrg 	  char tmp_iomsg[IOMSG_LEN] = "";
   2023      1.1  mrg 	  char *child_iomsg;
   2024      1.1  mrg 	  gfc_charlen_type child_iomsg_len;
   2025      1.1  mrg 	  int noiostat;
   2026      1.1  mrg 	  int *child_iostat = NULL;
   2027      1.1  mrg 	  char *iotype;
   2028      1.1  mrg 	  gfc_charlen_type iotype_len = f->u.udf.string_len;
   2029      1.1  mrg 
   2030      1.1  mrg 	  /* Build the iotype string.  */
   2031      1.1  mrg 	  if (iotype_len == 0)
   2032      1.1  mrg 	    {
   2033      1.1  mrg 	      iotype_len = 2;
   2034      1.1  mrg 	      iotype = dt;
   2035      1.1  mrg 	    }
   2036      1.1  mrg 	  else
   2037      1.1  mrg 	    iotype = get_dt_format (f->u.udf.string, &iotype_len);
   2038      1.1  mrg 
   2039      1.1  mrg 	  /* Set iostat, intent(out).  */
   2040      1.1  mrg 	  noiostat = 0;
   2041      1.1  mrg 	  child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
   2042      1.1  mrg 			  dtp->common.iostat : &noiostat;
   2043      1.1  mrg 
   2044      1.1  mrg 	  /* Set iomsg, intent(inout).  */
   2045      1.1  mrg 	  if (dtp->common.flags & IOPARM_HAS_IOMSG)
   2046      1.1  mrg 	    {
   2047      1.1  mrg 	      child_iomsg = dtp->common.iomsg;
   2048      1.1  mrg 	      child_iomsg_len = dtp->common.iomsg_len;
   2049      1.1  mrg 	    }
   2050      1.1  mrg 	  else
   2051      1.1  mrg 	    {
   2052      1.1  mrg 	      child_iomsg = tmp_iomsg;
   2053      1.1  mrg 	      child_iomsg_len = IOMSG_LEN;
   2054      1.1  mrg 	    }
   2055      1.1  mrg 
   2056      1.1  mrg 	  if (check_dtio_proc (dtp, f))
   2057      1.1  mrg 	    return;
   2058      1.1  mrg 
   2059      1.1  mrg 	  /* Call the user defined formatted WRITE procedure.  */
   2060      1.1  mrg 	  dtp->u.p.current_unit->child_dtio++;
   2061      1.1  mrg 
   2062      1.1  mrg 	  dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
   2063      1.1  mrg 			      child_iostat, child_iomsg,
   2064      1.1  mrg 			      iotype_len, child_iomsg_len);
   2065      1.1  mrg 	  dtp->u.p.current_unit->child_dtio--;
   2066      1.1  mrg 
   2067      1.1  mrg 	  if (f->u.udf.string_len != 0)
   2068      1.1  mrg 	    free (iotype);
   2069      1.1  mrg 	  /* Note: vlist is freed in free_format_data.  */
   2070      1.1  mrg 	  break;
   2071      1.1  mrg 
   2072      1.1  mrg 	case FMT_E:
   2073      1.1  mrg 	  if (n == 0)
   2074      1.1  mrg 	    goto need_data;
   2075      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   2076      1.1  mrg 	    return;
   2077  1.1.1.2  mrg 	  if (f->u.real.w == 0)
   2078  1.1.1.2  mrg 	    write_real_w0 (dtp, p, kind, f);
   2079  1.1.1.2  mrg 	  else
   2080  1.1.1.2  mrg 	    write_e (dtp, f, p, kind);
   2081      1.1  mrg 	  break;
   2082      1.1  mrg 
   2083      1.1  mrg 	case FMT_EN:
   2084      1.1  mrg 	  if (n == 0)
   2085      1.1  mrg 	    goto need_data;
   2086      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   2087      1.1  mrg 	    return;
   2088  1.1.1.2  mrg 	  if (f->u.real.w == 0)
   2089  1.1.1.2  mrg 	    write_real_w0 (dtp, p, kind, f);
   2090  1.1.1.2  mrg 	  else
   2091  1.1.1.2  mrg 	    write_en (dtp, f, p, kind);
   2092      1.1  mrg 	  break;
   2093      1.1  mrg 
   2094      1.1  mrg 	case FMT_ES:
   2095      1.1  mrg 	  if (n == 0)
   2096      1.1  mrg 	    goto need_data;
   2097      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   2098      1.1  mrg 	    return;
   2099  1.1.1.2  mrg 	  if (f->u.real.w == 0)
   2100  1.1.1.2  mrg 	    write_real_w0 (dtp, p, kind, f);
   2101  1.1.1.2  mrg 	  else
   2102  1.1.1.2  mrg 	    write_es (dtp, f, p, kind);
   2103      1.1  mrg 	  break;
   2104      1.1  mrg 
   2105      1.1  mrg 	case FMT_F:
   2106      1.1  mrg 	  if (n == 0)
   2107      1.1  mrg 	    goto need_data;
   2108      1.1  mrg 	  if (require_type (dtp, BT_REAL, type, f))
   2109      1.1  mrg 	    return;
   2110      1.1  mrg 	  write_f (dtp, f, p, kind);
   2111      1.1  mrg 	  break;
   2112      1.1  mrg 
   2113      1.1  mrg 	case FMT_G:
   2114      1.1  mrg 	  if (n == 0)
   2115      1.1  mrg 	    goto need_data;
   2116      1.1  mrg 	  switch (type)
   2117      1.1  mrg 	    {
   2118      1.1  mrg 	      case BT_INTEGER:
   2119      1.1  mrg 		write_i (dtp, f, p, kind);
   2120      1.1  mrg 		break;
   2121      1.1  mrg 	      case BT_LOGICAL:
   2122      1.1  mrg 		write_l (dtp, f, p, kind);
   2123      1.1  mrg 		break;
   2124      1.1  mrg 	      case BT_CHARACTER:
   2125      1.1  mrg 		if (kind == 4)
   2126      1.1  mrg 		  write_a_char4 (dtp, f, p, size);
   2127      1.1  mrg 		else
   2128      1.1  mrg 		  write_a (dtp, f, p, size);
   2129      1.1  mrg 		break;
   2130      1.1  mrg 	      case BT_REAL:
   2131      1.1  mrg 		if (f->u.real.w == 0)
   2132  1.1.1.2  mrg 		  write_real_w0 (dtp, p, kind, f);
   2133      1.1  mrg 		else
   2134      1.1  mrg 		  write_d (dtp, f, p, kind);
   2135      1.1  mrg 		break;
   2136      1.1  mrg 	      default:
   2137      1.1  mrg 		internal_error (&dtp->common,
   2138      1.1  mrg 				"formatted_transfer (): Bad type");
   2139      1.1  mrg 	    }
   2140      1.1  mrg 	  break;
   2141      1.1  mrg 
   2142      1.1  mrg 	case FMT_STRING:
   2143      1.1  mrg 	  consume_data_flag = 0;
   2144      1.1  mrg 	  write_constant_string (dtp, f);
   2145      1.1  mrg 	  break;
   2146      1.1  mrg 
   2147      1.1  mrg 	/* Format codes that don't transfer data.  */
   2148      1.1  mrg 	case FMT_X:
   2149      1.1  mrg 	case FMT_TR:
   2150      1.1  mrg 	  consume_data_flag = 0;
   2151      1.1  mrg 
   2152      1.1  mrg 	  dtp->u.p.skips += f->u.n;
   2153      1.1  mrg 	  pos = bytes_used + dtp->u.p.skips - 1;
   2154      1.1  mrg 	  dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
   2155      1.1  mrg 	  /* Writes occur just before the switch on f->format, above, so
   2156      1.1  mrg 	     that trailing blanks are suppressed, unless we are doing a
   2157      1.1  mrg 	     non-advancing write in which case we want to output the blanks
   2158      1.1  mrg 	     now.  */
   2159      1.1  mrg 	  if (dtp->u.p.advance_status == ADVANCE_NO)
   2160      1.1  mrg 	    {
   2161      1.1  mrg 	      write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
   2162      1.1  mrg 	      dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   2163      1.1  mrg 	    }
   2164      1.1  mrg 	  break;
   2165      1.1  mrg 
   2166      1.1  mrg 	case FMT_TL:
   2167      1.1  mrg 	case FMT_T:
   2168      1.1  mrg 	  consume_data_flag = 0;
   2169      1.1  mrg 
   2170      1.1  mrg 	  if (f->format == FMT_TL)
   2171      1.1  mrg 	    {
   2172      1.1  mrg 
   2173      1.1  mrg 	      /* Handle the special case when no bytes have been used yet.
   2174      1.1  mrg 	         Cannot go below zero. */
   2175      1.1  mrg 	      if (bytes_used == 0)
   2176      1.1  mrg 		{
   2177      1.1  mrg 		  dtp->u.p.pending_spaces -= f->u.n;
   2178      1.1  mrg 		  dtp->u.p.skips -= f->u.n;
   2179      1.1  mrg 		  dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
   2180      1.1  mrg 		}
   2181      1.1  mrg 
   2182      1.1  mrg 	      pos = bytes_used - f->u.n;
   2183      1.1  mrg 	    }
   2184      1.1  mrg 	  else /* FMT_T */
   2185      1.1  mrg 	    pos = f->u.n - dtp->u.p.pending_spaces - 1;
   2186      1.1  mrg 
   2187      1.1  mrg 	  /* Standard 10.6.1.1: excessive left tabbing is reset to the
   2188      1.1  mrg 	     left tab limit.  We do not check if the position has gone
   2189      1.1  mrg 	     beyond the end of record because a subsequent tab could
   2190      1.1  mrg 	     bring us back again.  */
   2191      1.1  mrg 	  pos = pos < 0 ? 0 : pos;
   2192      1.1  mrg 
   2193      1.1  mrg 	  dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
   2194      1.1  mrg 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
   2195      1.1  mrg 				    + pos - dtp->u.p.max_pos;
   2196      1.1  mrg 	  dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
   2197      1.1  mrg 				    ? 0 : dtp->u.p.pending_spaces;
   2198      1.1  mrg 	  break;
   2199      1.1  mrg 
   2200      1.1  mrg 	case FMT_S:
   2201      1.1  mrg 	  consume_data_flag = 0;
   2202  1.1.1.2  mrg 	  dtp->u.p.sign_status = SIGN_PROCDEFINED;
   2203      1.1  mrg 	  break;
   2204      1.1  mrg 
   2205      1.1  mrg 	case FMT_SS:
   2206      1.1  mrg 	  consume_data_flag = 0;
   2207  1.1.1.2  mrg 	  dtp->u.p.sign_status = SIGN_SUPPRESS;
   2208      1.1  mrg 	  break;
   2209      1.1  mrg 
   2210      1.1  mrg 	case FMT_SP:
   2211      1.1  mrg 	  consume_data_flag = 0;
   2212  1.1.1.2  mrg 	  dtp->u.p.sign_status = SIGN_PLUS;
   2213      1.1  mrg 	  break;
   2214      1.1  mrg 
   2215      1.1  mrg 	case FMT_BN:
   2216      1.1  mrg 	  consume_data_flag = 0 ;
   2217      1.1  mrg 	  dtp->u.p.blank_status = BLANK_NULL;
   2218      1.1  mrg 	  break;
   2219      1.1  mrg 
   2220      1.1  mrg 	case FMT_BZ:
   2221      1.1  mrg 	  consume_data_flag = 0;
   2222      1.1  mrg 	  dtp->u.p.blank_status = BLANK_ZERO;
   2223      1.1  mrg 	  break;
   2224      1.1  mrg 
   2225      1.1  mrg 	case FMT_DC:
   2226      1.1  mrg 	  consume_data_flag = 0;
   2227      1.1  mrg 	  dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
   2228      1.1  mrg 	  break;
   2229      1.1  mrg 
   2230      1.1  mrg 	case FMT_DP:
   2231      1.1  mrg 	  consume_data_flag = 0;
   2232      1.1  mrg 	  dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
   2233      1.1  mrg 	  break;
   2234      1.1  mrg 
   2235      1.1  mrg 	case FMT_RC:
   2236      1.1  mrg 	  consume_data_flag = 0;
   2237      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
   2238      1.1  mrg 	  break;
   2239      1.1  mrg 
   2240      1.1  mrg 	case FMT_RD:
   2241      1.1  mrg 	  consume_data_flag = 0;
   2242      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_DOWN;
   2243      1.1  mrg 	  break;
   2244      1.1  mrg 
   2245      1.1  mrg 	case FMT_RN:
   2246      1.1  mrg 	  consume_data_flag = 0;
   2247      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_NEAREST;
   2248      1.1  mrg 	  break;
   2249      1.1  mrg 
   2250      1.1  mrg 	case FMT_RP:
   2251      1.1  mrg 	  consume_data_flag = 0;
   2252      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
   2253      1.1  mrg 	  break;
   2254      1.1  mrg 
   2255      1.1  mrg 	case FMT_RU:
   2256      1.1  mrg 	  consume_data_flag = 0;
   2257      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_UP;
   2258      1.1  mrg 	  break;
   2259      1.1  mrg 
   2260      1.1  mrg 	case FMT_RZ:
   2261      1.1  mrg 	  consume_data_flag = 0;
   2262      1.1  mrg 	  dtp->u.p.current_unit->round_status = ROUND_ZERO;
   2263      1.1  mrg 	  break;
   2264      1.1  mrg 
   2265      1.1  mrg 	case FMT_P:
   2266      1.1  mrg 	  consume_data_flag = 0;
   2267      1.1  mrg 	  dtp->u.p.scale_factor = f->u.k;
   2268      1.1  mrg 	  break;
   2269      1.1  mrg 
   2270      1.1  mrg 	case FMT_DOLLAR:
   2271      1.1  mrg 	  consume_data_flag = 0;
   2272      1.1  mrg 	  dtp->u.p.seen_dollar = 1;
   2273      1.1  mrg 	  break;
   2274      1.1  mrg 
   2275      1.1  mrg 	case FMT_SLASH:
   2276      1.1  mrg 	  consume_data_flag = 0;
   2277      1.1  mrg 	  dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   2278      1.1  mrg 	  next_record (dtp, 0);
   2279      1.1  mrg 	  break;
   2280      1.1  mrg 
   2281      1.1  mrg 	case FMT_COLON:
   2282      1.1  mrg 	  /* A colon descriptor causes us to exit this loop (in
   2283      1.1  mrg 	     particular preventing another / descriptor from being
   2284      1.1  mrg 	     processed) unless there is another data item to be
   2285      1.1  mrg 	     transferred.  */
   2286      1.1  mrg 	  consume_data_flag = 0;
   2287      1.1  mrg 	  if (n == 0)
   2288      1.1  mrg 	    return;
   2289      1.1  mrg 	  break;
   2290      1.1  mrg 
   2291      1.1  mrg 	default:
   2292      1.1  mrg 	  internal_error (&dtp->common, "Bad format node");
   2293      1.1  mrg 	}
   2294      1.1  mrg 
   2295      1.1  mrg       /* Adjust the item count and data pointer.  */
   2296      1.1  mrg 
   2297      1.1  mrg       if ((consume_data_flag > 0) && (n > 0))
   2298      1.1  mrg 	{
   2299      1.1  mrg 	  n--;
   2300      1.1  mrg 	  p = ((char *) p) + size;
   2301      1.1  mrg 	}
   2302      1.1  mrg 
   2303      1.1  mrg       pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left;
   2304      1.1  mrg       dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
   2305      1.1  mrg     }
   2306      1.1  mrg 
   2307      1.1  mrg   return;
   2308      1.1  mrg 
   2309      1.1  mrg   /* Come here when we need a data descriptor but don't have one.  We
   2310      1.1  mrg      push the current format node back onto the input, then return and
   2311      1.1  mrg      let the user program call us back with the data.  */
   2312      1.1  mrg  need_data:
   2313      1.1  mrg   unget_format (dtp, f);
   2314      1.1  mrg }
   2315      1.1  mrg 
   2316      1.1  mrg   /* This function is first called from data_init_transfer to initiate the loop
   2317      1.1  mrg      over each item in the format, transferring data as required.  Subsequent
   2318      1.1  mrg      calls to this function occur for each data item foound in the READ/WRITE
   2319      1.1  mrg      statement.  The item_count is incremented for each call.  Since the first
   2320      1.1  mrg      call is from data_transfer_init, the item_count is always one greater than
   2321      1.1  mrg      the actual count number of the item being transferred.  */
   2322      1.1  mrg 
   2323      1.1  mrg static void
   2324      1.1  mrg formatted_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
   2325      1.1  mrg 		    size_t size, size_t nelems)
   2326      1.1  mrg {
   2327      1.1  mrg   size_t elem;
   2328      1.1  mrg   char *tmp;
   2329      1.1  mrg 
   2330      1.1  mrg   tmp = (char *) p;
   2331      1.1  mrg   size_t stride = type == BT_CHARACTER ?
   2332      1.1  mrg 		  size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
   2333      1.1  mrg   if (dtp->u.p.mode == READING)
   2334      1.1  mrg     {
   2335      1.1  mrg       /* Big loop over all the elements.  */
   2336      1.1  mrg       for (elem = 0; elem < nelems; elem++)
   2337      1.1  mrg 	{
   2338      1.1  mrg 	  dtp->u.p.item_count++;
   2339      1.1  mrg 	  formatted_transfer_scalar_read (dtp, type, tmp + stride*elem, kind, size);
   2340      1.1  mrg 	}
   2341      1.1  mrg     }
   2342      1.1  mrg   else
   2343      1.1  mrg     {
   2344      1.1  mrg       /* Big loop over all the elements.  */
   2345      1.1  mrg       for (elem = 0; elem < nelems; elem++)
   2346      1.1  mrg 	{
   2347      1.1  mrg 	  dtp->u.p.item_count++;
   2348      1.1  mrg 	  formatted_transfer_scalar_write (dtp, type, tmp + stride*elem, kind, size);
   2349      1.1  mrg 	}
   2350      1.1  mrg     }
   2351      1.1  mrg }
   2352      1.1  mrg 
   2353      1.1  mrg /* Wrapper function for I/O of scalar types.  If this should be an async I/O
   2354      1.1  mrg    request, queue it.  For a synchronous write on an async unit, perform the
   2355      1.1  mrg    wait operation and return an error.  For all synchronous writes, call the
   2356      1.1  mrg    right transfer function.  */
   2357      1.1  mrg 
   2358      1.1  mrg static void
   2359      1.1  mrg wrap_scalar_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
   2360      1.1  mrg 		      size_t size, size_t n_elem)
   2361      1.1  mrg {
   2362      1.1  mrg   if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
   2363      1.1  mrg     {
   2364      1.1  mrg       if (dtp->u.p.async)
   2365      1.1  mrg 	{
   2366      1.1  mrg 	  transfer_args args;
   2367      1.1  mrg 	  args.scalar.transfer = dtp->u.p.transfer;
   2368      1.1  mrg 	  args.scalar.arg_bt = type;
   2369      1.1  mrg 	  args.scalar.data = p;
   2370      1.1  mrg 	  args.scalar.i = kind;
   2371      1.1  mrg 	  args.scalar.s1 = size;
   2372      1.1  mrg 	  args.scalar.s2 = n_elem;
   2373      1.1  mrg 	  enqueue_transfer (dtp->u.p.current_unit->au, &args,
   2374      1.1  mrg 			    AIO_TRANSFER_SCALAR);
   2375      1.1  mrg 	  return;
   2376      1.1  mrg 	}
   2377      1.1  mrg     }
   2378      1.1  mrg   /* Come here if there was no asynchronous I/O to be scheduled.  */
   2379      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2380      1.1  mrg     return;
   2381      1.1  mrg 
   2382      1.1  mrg   dtp->u.p.transfer (dtp, type, p, kind, size, 1);
   2383      1.1  mrg }
   2384      1.1  mrg 
   2385      1.1  mrg 
   2386      1.1  mrg /* Data transfer entry points.  The type of the data entity is
   2387      1.1  mrg    implicit in the subroutine call.  This prevents us from having to
   2388      1.1  mrg    share a common enum with the compiler.  */
   2389      1.1  mrg 
   2390      1.1  mrg void
   2391      1.1  mrg transfer_integer (st_parameter_dt *dtp, void *p, int kind)
   2392      1.1  mrg {
   2393      1.1  mrg     wrap_scalar_transfer (dtp, BT_INTEGER, p, kind, kind, 1);
   2394      1.1  mrg }
   2395      1.1  mrg 
   2396      1.1  mrg void
   2397      1.1  mrg transfer_integer_write (st_parameter_dt *dtp, void *p, int kind)
   2398      1.1  mrg {
   2399      1.1  mrg   transfer_integer (dtp, p, kind);
   2400      1.1  mrg }
   2401      1.1  mrg 
   2402      1.1  mrg void
   2403      1.1  mrg transfer_real (st_parameter_dt *dtp, void *p, int kind)
   2404      1.1  mrg {
   2405      1.1  mrg   size_t size;
   2406      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2407      1.1  mrg     return;
   2408      1.1  mrg   size = size_from_real_kind (kind);
   2409      1.1  mrg   wrap_scalar_transfer (dtp, BT_REAL, p, kind, size, 1);
   2410      1.1  mrg }
   2411      1.1  mrg 
   2412      1.1  mrg void
   2413      1.1  mrg transfer_real_write (st_parameter_dt *dtp, void *p, int kind)
   2414      1.1  mrg {
   2415      1.1  mrg   transfer_real (dtp, p, kind);
   2416      1.1  mrg }
   2417      1.1  mrg 
   2418      1.1  mrg void
   2419      1.1  mrg transfer_logical (st_parameter_dt *dtp, void *p, int kind)
   2420      1.1  mrg {
   2421      1.1  mrg   wrap_scalar_transfer (dtp, BT_LOGICAL, p, kind, kind, 1);
   2422      1.1  mrg }
   2423      1.1  mrg 
   2424      1.1  mrg void
   2425      1.1  mrg transfer_logical_write (st_parameter_dt *dtp, void *p, int kind)
   2426      1.1  mrg {
   2427      1.1  mrg   transfer_logical (dtp, p, kind);
   2428      1.1  mrg }
   2429      1.1  mrg 
   2430      1.1  mrg void
   2431      1.1  mrg transfer_character (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
   2432      1.1  mrg {
   2433      1.1  mrg   static char *empty_string[0];
   2434      1.1  mrg 
   2435      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2436      1.1  mrg     return;
   2437      1.1  mrg 
   2438      1.1  mrg   /* Strings of zero length can have p == NULL, which confuses the
   2439      1.1  mrg      transfer routines into thinking we need more data elements.  To avoid
   2440      1.1  mrg      this, we give them a nice pointer.  */
   2441      1.1  mrg   if (len == 0 && p == NULL)
   2442      1.1  mrg     p = empty_string;
   2443      1.1  mrg 
   2444      1.1  mrg   /* Set kind here to 1.  */
   2445      1.1  mrg   wrap_scalar_transfer (dtp, BT_CHARACTER, p, 1, len, 1);
   2446      1.1  mrg }
   2447      1.1  mrg 
   2448      1.1  mrg void
   2449      1.1  mrg transfer_character_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
   2450      1.1  mrg {
   2451      1.1  mrg   transfer_character (dtp, p, len);
   2452      1.1  mrg }
   2453      1.1  mrg 
   2454      1.1  mrg void
   2455      1.1  mrg transfer_character_wide (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
   2456      1.1  mrg {
   2457      1.1  mrg   static char *empty_string[0];
   2458      1.1  mrg 
   2459      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2460      1.1  mrg     return;
   2461      1.1  mrg 
   2462      1.1  mrg   /* Strings of zero length can have p == NULL, which confuses the
   2463      1.1  mrg      transfer routines into thinking we need more data elements.  To avoid
   2464      1.1  mrg      this, we give them a nice pointer.  */
   2465      1.1  mrg   if (len == 0 && p == NULL)
   2466      1.1  mrg     p = empty_string;
   2467      1.1  mrg 
   2468      1.1  mrg   /* Here we pass the actual kind value.  */
   2469      1.1  mrg   wrap_scalar_transfer (dtp, BT_CHARACTER, p, kind, len, 1);
   2470      1.1  mrg }
   2471      1.1  mrg 
   2472      1.1  mrg void
   2473      1.1  mrg transfer_character_wide_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
   2474      1.1  mrg {
   2475      1.1  mrg   transfer_character_wide (dtp, p, len, kind);
   2476      1.1  mrg }
   2477      1.1  mrg 
   2478      1.1  mrg void
   2479      1.1  mrg transfer_complex (st_parameter_dt *dtp, void *p, int kind)
   2480      1.1  mrg {
   2481      1.1  mrg   size_t size;
   2482      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2483      1.1  mrg     return;
   2484      1.1  mrg   size = size_from_complex_kind (kind);
   2485      1.1  mrg   wrap_scalar_transfer (dtp, BT_COMPLEX, p, kind, size, 1);
   2486      1.1  mrg }
   2487      1.1  mrg 
   2488      1.1  mrg void
   2489      1.1  mrg transfer_complex_write (st_parameter_dt *dtp, void *p, int kind)
   2490      1.1  mrg {
   2491      1.1  mrg   transfer_complex (dtp, p, kind);
   2492      1.1  mrg }
   2493      1.1  mrg 
   2494      1.1  mrg void
   2495      1.1  mrg transfer_array_inner (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
   2496      1.1  mrg 		      gfc_charlen_type charlen)
   2497      1.1  mrg {
   2498      1.1  mrg   index_type count[GFC_MAX_DIMENSIONS];
   2499      1.1  mrg   index_type extent[GFC_MAX_DIMENSIONS];
   2500      1.1  mrg   index_type stride[GFC_MAX_DIMENSIONS];
   2501      1.1  mrg   index_type stride0, rank, size, n;
   2502      1.1  mrg   size_t tsize;
   2503      1.1  mrg   char *data;
   2504      1.1  mrg   bt iotype;
   2505      1.1  mrg 
   2506      1.1  mrg   /* Adjust item_count before emitting error message.  */
   2507      1.1  mrg 
   2508      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2509      1.1  mrg     return;
   2510      1.1  mrg 
   2511      1.1  mrg   iotype = (bt) GFC_DESCRIPTOR_TYPE (desc);
   2512      1.1  mrg   size = iotype == BT_CHARACTER ? charlen : GFC_DESCRIPTOR_SIZE (desc);
   2513      1.1  mrg 
   2514      1.1  mrg   rank = GFC_DESCRIPTOR_RANK (desc);
   2515      1.1  mrg 
   2516      1.1  mrg   for (n = 0; n < rank; n++)
   2517      1.1  mrg     {
   2518      1.1  mrg       count[n] = 0;
   2519      1.1  mrg       stride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(desc,n);
   2520      1.1  mrg       extent[n] = GFC_DESCRIPTOR_EXTENT(desc,n);
   2521      1.1  mrg 
   2522      1.1  mrg       /* If the extent of even one dimension is zero, then the entire
   2523      1.1  mrg 	 array section contains zero elements, so we return after writing
   2524      1.1  mrg 	 a zero array record.  */
   2525      1.1  mrg       if (extent[n] <= 0)
   2526      1.1  mrg 	{
   2527      1.1  mrg 	  data = NULL;
   2528      1.1  mrg 	  tsize = 0;
   2529      1.1  mrg 	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
   2530      1.1  mrg 	  return;
   2531      1.1  mrg 	}
   2532      1.1  mrg     }
   2533      1.1  mrg 
   2534      1.1  mrg   stride0 = stride[0];
   2535      1.1  mrg 
   2536      1.1  mrg   /* If the innermost dimension has a stride of 1, we can do the transfer
   2537      1.1  mrg      in contiguous chunks.  */
   2538      1.1  mrg   if (stride0 == size)
   2539      1.1  mrg     tsize = extent[0];
   2540      1.1  mrg   else
   2541      1.1  mrg     tsize = 1;
   2542      1.1  mrg 
   2543      1.1  mrg   data = GFC_DESCRIPTOR_DATA (desc);
   2544      1.1  mrg 
   2545      1.1  mrg   /* When reading, we need to check endfile conditions so we do not miss
   2546      1.1  mrg      an END=label.  Make this separate so we do not have an extra test
   2547      1.1  mrg      in a tight loop when it is not needed.  */
   2548      1.1  mrg 
   2549      1.1  mrg   if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
   2550      1.1  mrg     {
   2551      1.1  mrg       while (data)
   2552      1.1  mrg 	{
   2553      1.1  mrg 	  if (unlikely (dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
   2554      1.1  mrg 	    return;
   2555      1.1  mrg 
   2556      1.1  mrg 	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
   2557      1.1  mrg 	  data += stride0 * tsize;
   2558      1.1  mrg 	  count[0] += tsize;
   2559      1.1  mrg 	  n = 0;
   2560      1.1  mrg 	  while (count[n] == extent[n])
   2561      1.1  mrg 	    {
   2562      1.1  mrg 	      count[n] = 0;
   2563      1.1  mrg 	      data -= stride[n] * extent[n];
   2564      1.1  mrg 	      n++;
   2565      1.1  mrg 	      if (n == rank)
   2566      1.1  mrg 		{
   2567      1.1  mrg 		  data = NULL;
   2568      1.1  mrg 		  break;
   2569      1.1  mrg 		}
   2570      1.1  mrg 	      else
   2571      1.1  mrg 		{
   2572      1.1  mrg 		  count[n]++;
   2573      1.1  mrg 		  data += stride[n];
   2574      1.1  mrg 		}
   2575      1.1  mrg 	    }
   2576      1.1  mrg 	}
   2577      1.1  mrg     }
   2578      1.1  mrg   else
   2579      1.1  mrg     {
   2580      1.1  mrg       while (data)
   2581      1.1  mrg 	{
   2582      1.1  mrg 	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
   2583      1.1  mrg 	  data += stride0 * tsize;
   2584      1.1  mrg 	  count[0] += tsize;
   2585      1.1  mrg 	  n = 0;
   2586      1.1  mrg 	  while (count[n] == extent[n])
   2587      1.1  mrg 	    {
   2588      1.1  mrg 	      count[n] = 0;
   2589      1.1  mrg 	      data -= stride[n] * extent[n];
   2590      1.1  mrg 	      n++;
   2591      1.1  mrg 	      if (n == rank)
   2592      1.1  mrg 		{
   2593      1.1  mrg 		  data = NULL;
   2594      1.1  mrg 		  break;
   2595      1.1  mrg 		}
   2596      1.1  mrg 	      else
   2597      1.1  mrg 		{
   2598      1.1  mrg 		  count[n]++;
   2599      1.1  mrg 		  data += stride[n];
   2600      1.1  mrg 		}
   2601      1.1  mrg 	    }
   2602      1.1  mrg 	}
   2603      1.1  mrg     }
   2604      1.1  mrg }
   2605      1.1  mrg 
   2606      1.1  mrg void
   2607      1.1  mrg transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
   2608      1.1  mrg 	        gfc_charlen_type charlen)
   2609      1.1  mrg {
   2610      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2611      1.1  mrg     return;
   2612      1.1  mrg 
   2613      1.1  mrg   if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
   2614      1.1  mrg     {
   2615      1.1  mrg       if (dtp->u.p.async)
   2616      1.1  mrg 	{
   2617      1.1  mrg 	  transfer_args args;
   2618      1.1  mrg 	  size_t sz = sizeof (gfc_array_char)
   2619      1.1  mrg 			+ sizeof (descriptor_dimension)
   2620      1.1  mrg        			* GFC_DESCRIPTOR_RANK (desc);
   2621      1.1  mrg 	  args.array.desc = xmalloc (sz);
   2622      1.1  mrg 	  NOTE ("desc = %p", (void *) args.array.desc);
   2623      1.1  mrg 	  memcpy (args.array.desc, desc, sz);
   2624      1.1  mrg 	  args.array.kind = kind;
   2625      1.1  mrg 	  args.array.charlen = charlen;
   2626      1.1  mrg 	  enqueue_transfer (dtp->u.p.current_unit->au, &args,
   2627      1.1  mrg 			    AIO_TRANSFER_ARRAY);
   2628      1.1  mrg 	  return;
   2629      1.1  mrg 	}
   2630      1.1  mrg     }
   2631      1.1  mrg   /* Come here if there was no asynchronous I/O to be scheduled.  */
   2632      1.1  mrg   transfer_array_inner (dtp, desc, kind, charlen);
   2633      1.1  mrg }
   2634      1.1  mrg 
   2635      1.1  mrg 
   2636      1.1  mrg void
   2637      1.1  mrg transfer_array_write (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
   2638      1.1  mrg 		      gfc_charlen_type charlen)
   2639      1.1  mrg {
   2640      1.1  mrg   transfer_array (dtp, desc, kind, charlen);
   2641      1.1  mrg }
   2642      1.1  mrg 
   2643      1.1  mrg 
   2644      1.1  mrg /* User defined input/output iomsg. */
   2645      1.1  mrg 
   2646      1.1  mrg #define IOMSG_LEN 256
   2647      1.1  mrg 
   2648      1.1  mrg void
   2649      1.1  mrg transfer_derived (st_parameter_dt *parent, void *dtio_source, void *dtio_proc)
   2650      1.1  mrg {
   2651      1.1  mrg   if (parent->u.p.current_unit)
   2652      1.1  mrg     {
   2653      1.1  mrg       if (parent->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   2654      1.1  mrg 	parent->u.p.ufdtio_ptr = (unformatted_dtio) dtio_proc;
   2655      1.1  mrg       else
   2656      1.1  mrg 	parent->u.p.fdtio_ptr = (formatted_dtio) dtio_proc;
   2657      1.1  mrg     }
   2658      1.1  mrg   wrap_scalar_transfer (parent, BT_CLASS, dtio_source, 0, 0, 1);
   2659      1.1  mrg }
   2660      1.1  mrg 
   2661      1.1  mrg 
   2662      1.1  mrg /* Preposition a sequential unformatted file while reading.  */
   2663      1.1  mrg 
   2664      1.1  mrg static void
   2665      1.1  mrg us_read (st_parameter_dt *dtp, int continued)
   2666      1.1  mrg {
   2667      1.1  mrg   ssize_t n, nr;
   2668      1.1  mrg   GFC_INTEGER_4 i4;
   2669      1.1  mrg   GFC_INTEGER_8 i8;
   2670      1.1  mrg   gfc_offset i;
   2671      1.1  mrg 
   2672      1.1  mrg   if (compile_options.record_marker == 0)
   2673      1.1  mrg     n = sizeof (GFC_INTEGER_4);
   2674      1.1  mrg   else
   2675      1.1  mrg     n = compile_options.record_marker;
   2676      1.1  mrg 
   2677      1.1  mrg   nr = sread (dtp->u.p.current_unit->s, &i, n);
   2678      1.1  mrg   if (unlikely (nr < 0))
   2679      1.1  mrg     {
   2680      1.1  mrg       generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
   2681      1.1  mrg       return;
   2682      1.1  mrg     }
   2683      1.1  mrg   else if (nr == 0)
   2684      1.1  mrg     {
   2685      1.1  mrg       hit_eof (dtp);
   2686      1.1  mrg       return;  /* end of file */
   2687      1.1  mrg     }
   2688      1.1  mrg   else if (unlikely (n != nr))
   2689      1.1  mrg     {
   2690      1.1  mrg       generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
   2691      1.1  mrg       return;
   2692      1.1  mrg     }
   2693      1.1  mrg 
   2694      1.1  mrg   /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here.  */
   2695      1.1  mrg   if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
   2696      1.1  mrg     {
   2697      1.1  mrg       switch (nr)
   2698      1.1  mrg 	{
   2699      1.1  mrg 	case sizeof(GFC_INTEGER_4):
   2700      1.1  mrg 	  memcpy (&i4, &i, sizeof (i4));
   2701      1.1  mrg 	  i = i4;
   2702      1.1  mrg 	  break;
   2703      1.1  mrg 
   2704      1.1  mrg 	case sizeof(GFC_INTEGER_8):
   2705      1.1  mrg 	  memcpy (&i8, &i, sizeof (i8));
   2706      1.1  mrg 	  i = i8;
   2707      1.1  mrg 	  break;
   2708      1.1  mrg 
   2709      1.1  mrg 	default:
   2710      1.1  mrg 	  runtime_error ("Illegal value for record marker");
   2711      1.1  mrg 	  break;
   2712      1.1  mrg 	}
   2713      1.1  mrg     }
   2714      1.1  mrg   else
   2715      1.1  mrg     {
   2716      1.1  mrg       uint32_t u32;
   2717      1.1  mrg       uint64_t u64;
   2718      1.1  mrg       switch (nr)
   2719      1.1  mrg 	{
   2720      1.1  mrg 	case sizeof(GFC_INTEGER_4):
   2721      1.1  mrg 	  memcpy (&u32, &i, sizeof (u32));
   2722      1.1  mrg 	  u32 = __builtin_bswap32 (u32);
   2723      1.1  mrg 	  memcpy (&i4, &u32, sizeof (i4));
   2724      1.1  mrg 	  i = i4;
   2725      1.1  mrg 	  break;
   2726      1.1  mrg 
   2727      1.1  mrg 	case sizeof(GFC_INTEGER_8):
   2728      1.1  mrg 	  memcpy (&u64, &i, sizeof (u64));
   2729      1.1  mrg 	  u64 = __builtin_bswap64 (u64);
   2730      1.1  mrg 	  memcpy (&i8, &u64, sizeof (i8));
   2731      1.1  mrg 	  i = i8;
   2732      1.1  mrg 	  break;
   2733      1.1  mrg 
   2734      1.1  mrg 	default:
   2735      1.1  mrg 	  runtime_error ("Illegal value for record marker");
   2736      1.1  mrg 	  break;
   2737      1.1  mrg 	}
   2738      1.1  mrg     }
   2739      1.1  mrg 
   2740      1.1  mrg   if (i >= 0)
   2741      1.1  mrg     {
   2742      1.1  mrg       dtp->u.p.current_unit->bytes_left_subrecord = i;
   2743      1.1  mrg       dtp->u.p.current_unit->continued = 0;
   2744      1.1  mrg     }
   2745      1.1  mrg   else
   2746      1.1  mrg     {
   2747      1.1  mrg       dtp->u.p.current_unit->bytes_left_subrecord = -i;
   2748      1.1  mrg       dtp->u.p.current_unit->continued = 1;
   2749      1.1  mrg     }
   2750      1.1  mrg 
   2751      1.1  mrg   if (! continued)
   2752      1.1  mrg     dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   2753      1.1  mrg }
   2754      1.1  mrg 
   2755      1.1  mrg 
   2756      1.1  mrg /* Preposition a sequential unformatted file while writing.  This
   2757      1.1  mrg    amount to writing a bogus length that will be filled in later.  */
   2758      1.1  mrg 
   2759      1.1  mrg static void
   2760      1.1  mrg us_write (st_parameter_dt *dtp, int continued)
   2761      1.1  mrg {
   2762      1.1  mrg   ssize_t nbytes;
   2763      1.1  mrg   gfc_offset dummy;
   2764      1.1  mrg 
   2765      1.1  mrg   dummy = 0;
   2766      1.1  mrg 
   2767      1.1  mrg   if (compile_options.record_marker == 0)
   2768      1.1  mrg     nbytes = sizeof (GFC_INTEGER_4);
   2769      1.1  mrg   else
   2770      1.1  mrg     nbytes = compile_options.record_marker ;
   2771      1.1  mrg 
   2772      1.1  mrg   if (swrite (dtp->u.p.current_unit->s, &dummy, nbytes) != nbytes)
   2773      1.1  mrg     generate_error (&dtp->common, LIBERROR_OS, NULL);
   2774      1.1  mrg 
   2775      1.1  mrg   /* For sequential unformatted, if RECL= was not specified in the OPEN
   2776      1.1  mrg      we write until we have more bytes than can fit in the subrecord
   2777      1.1  mrg      markers, then we write a new subrecord.  */
   2778      1.1  mrg 
   2779      1.1  mrg   dtp->u.p.current_unit->bytes_left_subrecord =
   2780      1.1  mrg     dtp->u.p.current_unit->recl_subrecord;
   2781      1.1  mrg   dtp->u.p.current_unit->continued = continued;
   2782      1.1  mrg }
   2783      1.1  mrg 
   2784      1.1  mrg 
   2785      1.1  mrg /* Position to the next record prior to transfer.  We are assumed to
   2786      1.1  mrg    be before the next record.  We also calculate the bytes in the next
   2787      1.1  mrg    record.  */
   2788      1.1  mrg 
   2789      1.1  mrg static void
   2790      1.1  mrg pre_position (st_parameter_dt *dtp)
   2791      1.1  mrg {
   2792      1.1  mrg   if (dtp->u.p.current_unit->current_record)
   2793      1.1  mrg     return;			/* Already positioned.  */
   2794      1.1  mrg 
   2795      1.1  mrg   switch (current_mode (dtp))
   2796      1.1  mrg     {
   2797      1.1  mrg     case FORMATTED_STREAM:
   2798      1.1  mrg     case UNFORMATTED_STREAM:
   2799      1.1  mrg       /* There are no records with stream I/O.  If the position was specified
   2800      1.1  mrg 	 data_transfer_init has already positioned the file. If no position
   2801      1.1  mrg 	 was specified, we continue from where we last left off.  I.e.
   2802      1.1  mrg 	 there is nothing to do here.  */
   2803      1.1  mrg       break;
   2804      1.1  mrg 
   2805      1.1  mrg     case UNFORMATTED_SEQUENTIAL:
   2806      1.1  mrg       if (dtp->u.p.mode == READING)
   2807      1.1  mrg 	us_read (dtp, 0);
   2808      1.1  mrg       else
   2809      1.1  mrg 	us_write (dtp, 0);
   2810      1.1  mrg 
   2811      1.1  mrg       break;
   2812      1.1  mrg 
   2813      1.1  mrg     case FORMATTED_SEQUENTIAL:
   2814      1.1  mrg     case FORMATTED_DIRECT:
   2815      1.1  mrg     case UNFORMATTED_DIRECT:
   2816      1.1  mrg       dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   2817      1.1  mrg       break;
   2818  1.1.1.2  mrg     case FORMATTED_UNSPECIFIED:
   2819  1.1.1.2  mrg       gcc_unreachable ();
   2820      1.1  mrg     }
   2821      1.1  mrg 
   2822      1.1  mrg   dtp->u.p.current_unit->current_record = 1;
   2823      1.1  mrg }
   2824      1.1  mrg 
   2825      1.1  mrg 
   2826      1.1  mrg /* Initialize things for a data transfer.  This code is common for
   2827      1.1  mrg    both reading and writing.  */
   2828      1.1  mrg 
   2829      1.1  mrg static void
   2830      1.1  mrg data_transfer_init (st_parameter_dt *dtp, int read_flag)
   2831      1.1  mrg {
   2832      1.1  mrg   unit_flags u_flags;  /* Used for creating a unit if needed.  */
   2833      1.1  mrg   GFC_INTEGER_4 cf = dtp->common.flags;
   2834      1.1  mrg   namelist_info *ionml;
   2835      1.1  mrg   async_unit *au;
   2836      1.1  mrg 
   2837      1.1  mrg   NOTE ("data_transfer_init");
   2838      1.1  mrg 
   2839      1.1  mrg   ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL;
   2840      1.1  mrg 
   2841      1.1  mrg   memset (&dtp->u.p, 0, sizeof (dtp->u.p));
   2842      1.1  mrg 
   2843      1.1  mrg   dtp->u.p.ionml = ionml;
   2844      1.1  mrg   dtp->u.p.mode = read_flag ? READING : WRITING;
   2845      1.1  mrg   dtp->u.p.namelist_mode = 0;
   2846      1.1  mrg   dtp->u.p.cc.len = 0;
   2847      1.1  mrg 
   2848      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   2849      1.1  mrg     return;
   2850      1.1  mrg 
   2851      1.1  mrg   dtp->u.p.current_unit = get_unit (dtp, 1);
   2852      1.1  mrg 
   2853      1.1  mrg   if (dtp->u.p.current_unit == NULL)
   2854      1.1  mrg     {
   2855      1.1  mrg       /* This means we tried to access an external unit < 0 without
   2856      1.1  mrg 	 having opened it first with NEWUNIT=.  */
   2857      1.1  mrg       generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   2858      1.1  mrg 		      "Unit number is negative and unit was not already "
   2859      1.1  mrg 		      "opened with OPEN(NEWUNIT=...)");
   2860      1.1  mrg       return;
   2861      1.1  mrg     }
   2862      1.1  mrg   else if (dtp->u.p.current_unit->s == NULL)
   2863      1.1  mrg     {  /* Open the unit with some default flags.  */
   2864      1.1  mrg       st_parameter_open opp;
   2865      1.1  mrg       unit_convert conv;
   2866      1.1  mrg       NOTE ("Open the unit with some default flags.");
   2867      1.1  mrg       memset (&u_flags, '\0', sizeof (u_flags));
   2868      1.1  mrg       u_flags.access = ACCESS_SEQUENTIAL;
   2869      1.1  mrg       u_flags.action = ACTION_READWRITE;
   2870      1.1  mrg 
   2871      1.1  mrg       /* Is it unformatted?  */
   2872      1.1  mrg       if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
   2873      1.1  mrg 		  | IOPARM_DT_IONML_SET)))
   2874      1.1  mrg 	u_flags.form = FORM_UNFORMATTED;
   2875      1.1  mrg       else
   2876      1.1  mrg 	u_flags.form = FORM_UNSPECIFIED;
   2877      1.1  mrg 
   2878      1.1  mrg       u_flags.delim = DELIM_UNSPECIFIED;
   2879      1.1  mrg       u_flags.blank = BLANK_UNSPECIFIED;
   2880      1.1  mrg       u_flags.pad = PAD_UNSPECIFIED;
   2881      1.1  mrg       u_flags.decimal = DECIMAL_UNSPECIFIED;
   2882      1.1  mrg       u_flags.encoding = ENCODING_UNSPECIFIED;
   2883      1.1  mrg       u_flags.async = ASYNC_UNSPECIFIED;
   2884      1.1  mrg       u_flags.round = ROUND_UNSPECIFIED;
   2885      1.1  mrg       u_flags.sign = SIGN_UNSPECIFIED;
   2886      1.1  mrg       u_flags.share = SHARE_UNSPECIFIED;
   2887      1.1  mrg       u_flags.cc = CC_UNSPECIFIED;
   2888      1.1  mrg       u_flags.readonly = 0;
   2889      1.1  mrg 
   2890      1.1  mrg       u_flags.status = STATUS_UNKNOWN;
   2891      1.1  mrg 
   2892      1.1  mrg       conv = get_unformatted_convert (dtp->common.unit);
   2893      1.1  mrg 
   2894      1.1  mrg       if (conv == GFC_CONVERT_NONE)
   2895      1.1  mrg 	conv = compile_options.convert;
   2896      1.1  mrg 
   2897      1.1  mrg       switch (conv)
   2898      1.1  mrg 	{
   2899      1.1  mrg 	case GFC_CONVERT_NATIVE:
   2900      1.1  mrg 	case GFC_CONVERT_SWAP:
   2901      1.1  mrg 	  break;
   2902      1.1  mrg 
   2903      1.1  mrg 	case GFC_CONVERT_BIG:
   2904      1.1  mrg 	  conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
   2905      1.1  mrg 	  break;
   2906      1.1  mrg 
   2907      1.1  mrg 	case GFC_CONVERT_LITTLE:
   2908      1.1  mrg 	  conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
   2909      1.1  mrg 	  break;
   2910      1.1  mrg 
   2911      1.1  mrg 	default:
   2912      1.1  mrg 	  internal_error (&opp.common, "Illegal value for CONVERT");
   2913      1.1  mrg 	  break;
   2914      1.1  mrg 	}
   2915      1.1  mrg 
   2916      1.1  mrg       u_flags.convert = conv;
   2917      1.1  mrg 
   2918      1.1  mrg       opp.common = dtp->common;
   2919      1.1  mrg       opp.common.flags &= IOPARM_COMMON_MASK;
   2920      1.1  mrg       dtp->u.p.current_unit = new_unit (&opp, dtp->u.p.current_unit, &u_flags);
   2921      1.1  mrg       dtp->common.flags &= ~IOPARM_COMMON_MASK;
   2922      1.1  mrg       dtp->common.flags |= (opp.common.flags & IOPARM_COMMON_MASK);
   2923      1.1  mrg       if (dtp->u.p.current_unit == NULL)
   2924      1.1  mrg 	return;
   2925      1.1  mrg     }
   2926      1.1  mrg 
   2927      1.1  mrg   if (dtp->u.p.current_unit->child_dtio == 0)
   2928      1.1  mrg     {
   2929      1.1  mrg       if ((cf & IOPARM_DT_HAS_SIZE) != 0)
   2930      1.1  mrg 	{
   2931      1.1  mrg 	  dtp->u.p.current_unit->has_size = true;
   2932      1.1  mrg 	  /* Initialize the count.  */
   2933      1.1  mrg 	  dtp->u.p.current_unit->size_used = 0;
   2934      1.1  mrg 	}
   2935      1.1  mrg       else
   2936      1.1  mrg 	dtp->u.p.current_unit->has_size = false;
   2937      1.1  mrg     }
   2938      1.1  mrg   else if (dtp->u.p.current_unit->internal_unit_kind > 0)
   2939      1.1  mrg     dtp->u.p.unit_is_internal = 1;
   2940      1.1  mrg 
   2941      1.1  mrg   if ((cf & IOPARM_DT_HAS_ASYNCHRONOUS) != 0)
   2942      1.1  mrg     {
   2943      1.1  mrg       int f;
   2944      1.1  mrg       f = find_option (&dtp->common, dtp->asynchronous, dtp->asynchronous_len,
   2945      1.1  mrg 		       async_opt, "Bad ASYNCHRONOUS in data transfer "
   2946      1.1  mrg 		       "statement");
   2947      1.1  mrg       if (f == ASYNC_YES && dtp->u.p.current_unit->flags.async != ASYNC_YES)
   2948      1.1  mrg 	{
   2949      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   2950      1.1  mrg 			  "ASYNCHRONOUS transfer without "
   2951      1.1  mrg 			  "ASYHCRONOUS='YES' in OPEN");
   2952      1.1  mrg 	  return;
   2953      1.1  mrg 	}
   2954      1.1  mrg       dtp->u.p.async = f == ASYNC_YES;
   2955      1.1  mrg     }
   2956      1.1  mrg 
   2957      1.1  mrg   au = dtp->u.p.current_unit->au;
   2958      1.1  mrg   if (au)
   2959      1.1  mrg     {
   2960      1.1  mrg       if (dtp->u.p.async)
   2961      1.1  mrg 	{
   2962      1.1  mrg 	  /* If this is an asynchronous I/O statement, collect errors and
   2963      1.1  mrg 	     return if there are any.  */
   2964      1.1  mrg 	  if (collect_async_errors (&dtp->common, au))
   2965      1.1  mrg 	    return;
   2966      1.1  mrg 	}
   2967      1.1  mrg       else
   2968      1.1  mrg 	{
   2969      1.1  mrg 	  /* Synchronous statement: Perform a wait operation for any pending
   2970      1.1  mrg 	     asynchronous I/O.  This needs to be done before all other error
   2971      1.1  mrg 	     checks.  See F2008, 9.6.4.1.  */
   2972      1.1  mrg 	  if (async_wait (&(dtp->common), au))
   2973      1.1  mrg 	    return;
   2974      1.1  mrg 	}
   2975      1.1  mrg     }
   2976      1.1  mrg 
   2977      1.1  mrg   /* Check the action.  */
   2978      1.1  mrg 
   2979      1.1  mrg   if (read_flag && dtp->u.p.current_unit->flags.action == ACTION_WRITE)
   2980      1.1  mrg     {
   2981      1.1  mrg       generate_error (&dtp->common, LIBERROR_BAD_ACTION,
   2982      1.1  mrg 		      "Cannot read from file opened for WRITE");
   2983      1.1  mrg       return;
   2984      1.1  mrg     }
   2985      1.1  mrg 
   2986      1.1  mrg   if (!read_flag && dtp->u.p.current_unit->flags.action == ACTION_READ)
   2987      1.1  mrg     {
   2988      1.1  mrg       generate_error (&dtp->common, LIBERROR_BAD_ACTION,
   2989      1.1  mrg 		      "Cannot write to file opened for READ");
   2990      1.1  mrg       return;
   2991      1.1  mrg     }
   2992      1.1  mrg 
   2993      1.1  mrg   dtp->u.p.first_item = 1;
   2994      1.1  mrg 
   2995      1.1  mrg   /* Check the format.  */
   2996      1.1  mrg 
   2997      1.1  mrg   if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
   2998      1.1  mrg     parse_format (dtp);
   2999      1.1  mrg 
   3000      1.1  mrg   if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
   3001      1.1  mrg       && (cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
   3002      1.1  mrg 	 != 0)
   3003      1.1  mrg     {
   3004      1.1  mrg       generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3005      1.1  mrg 		      "Format present for UNFORMATTED data transfer");
   3006      1.1  mrg       return;
   3007      1.1  mrg     }
   3008      1.1  mrg 
   3009      1.1  mrg   if ((cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0 && dtp->u.p.ionml != NULL)
   3010      1.1  mrg      {
   3011      1.1  mrg 	if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
   3012      1.1  mrg 	  {
   3013      1.1  mrg 	    generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3014      1.1  mrg 			"A format cannot be specified with a namelist");
   3015      1.1  mrg 	    return;
   3016      1.1  mrg 	  }
   3017      1.1  mrg      }
   3018      1.1  mrg   else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
   3019      1.1  mrg 	   !(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT)))
   3020      1.1  mrg     {
   3021      1.1  mrg       generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3022      1.1  mrg 		      "Missing format for FORMATTED data transfer");
   3023      1.1  mrg       return;
   3024      1.1  mrg     }
   3025      1.1  mrg 
   3026      1.1  mrg   if (is_internal_unit (dtp)
   3027      1.1  mrg       && dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   3028      1.1  mrg     {
   3029      1.1  mrg       generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3030      1.1  mrg 		      "Internal file cannot be accessed by UNFORMATTED "
   3031      1.1  mrg 		      "data transfer");
   3032      1.1  mrg       return;
   3033      1.1  mrg     }
   3034      1.1  mrg 
   3035      1.1  mrg   /* Check the record or position number.  */
   3036      1.1  mrg 
   3037      1.1  mrg   if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT
   3038      1.1  mrg       && (cf & IOPARM_DT_HAS_REC) == 0)
   3039      1.1  mrg     {
   3040      1.1  mrg       generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
   3041      1.1  mrg 		      "Direct access data transfer requires record number");
   3042      1.1  mrg       return;
   3043      1.1  mrg     }
   3044      1.1  mrg 
   3045      1.1  mrg   if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
   3046      1.1  mrg     {
   3047      1.1  mrg       if ((cf & IOPARM_DT_HAS_REC) != 0)
   3048      1.1  mrg 	{
   3049      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3050      1.1  mrg 			"Record number not allowed for sequential access "
   3051      1.1  mrg 			"data transfer");
   3052      1.1  mrg 	  return;
   3053      1.1  mrg 	}
   3054      1.1  mrg 
   3055      1.1  mrg       if (compile_options.warn_std &&
   3056      1.1  mrg 	  dtp->u.p.current_unit->endfile == AFTER_ENDFILE)
   3057      1.1  mrg       	{
   3058      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3059      1.1  mrg 			"Sequential READ or WRITE not allowed after "
   3060      1.1  mrg 			"EOF marker, possibly use REWIND or BACKSPACE");
   3061      1.1  mrg 	  return;
   3062      1.1  mrg 	}
   3063      1.1  mrg     }
   3064      1.1  mrg 
   3065      1.1  mrg   /* Process the ADVANCE option.  */
   3066      1.1  mrg 
   3067      1.1  mrg   dtp->u.p.advance_status
   3068      1.1  mrg     = !(cf & IOPARM_DT_HAS_ADVANCE) ? ADVANCE_UNSPECIFIED :
   3069      1.1  mrg       find_option (&dtp->common, dtp->advance, dtp->advance_len, advance_opt,
   3070      1.1  mrg 		   "Bad ADVANCE parameter in data transfer statement");
   3071      1.1  mrg 
   3072      1.1  mrg   if (dtp->u.p.advance_status != ADVANCE_UNSPECIFIED)
   3073      1.1  mrg     {
   3074      1.1  mrg       if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
   3075      1.1  mrg 	{
   3076      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3077      1.1  mrg 			  "ADVANCE specification conflicts with sequential "
   3078      1.1  mrg 			  "access");
   3079      1.1  mrg 	  return;
   3080      1.1  mrg 	}
   3081      1.1  mrg 
   3082      1.1  mrg       if (is_internal_unit (dtp))
   3083      1.1  mrg 	{
   3084      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3085      1.1  mrg 			  "ADVANCE specification conflicts with internal file");
   3086      1.1  mrg 	  return;
   3087      1.1  mrg 	}
   3088      1.1  mrg 
   3089      1.1  mrg       if ((cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
   3090      1.1  mrg 	  != IOPARM_DT_HAS_FORMAT)
   3091      1.1  mrg 	{
   3092      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3093      1.1  mrg 			  "ADVANCE specification requires an explicit format");
   3094      1.1  mrg 	  return;
   3095      1.1  mrg 	}
   3096      1.1  mrg     }
   3097      1.1  mrg 
   3098      1.1  mrg   /* Child IO is non-advancing and any ADVANCE= specifier is ignored.
   3099      1.1  mrg      F2008 9.6.2.4  */
   3100      1.1  mrg   if (dtp->u.p.current_unit->child_dtio  > 0)
   3101      1.1  mrg     dtp->u.p.advance_status = ADVANCE_NO;
   3102      1.1  mrg 
   3103      1.1  mrg   if (read_flag)
   3104      1.1  mrg     {
   3105      1.1  mrg       dtp->u.p.current_unit->previous_nonadvancing_write = 0;
   3106      1.1  mrg 
   3107      1.1  mrg       if ((cf & IOPARM_EOR) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
   3108      1.1  mrg 	{
   3109      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
   3110      1.1  mrg 			  "EOR specification requires an ADVANCE specification "
   3111      1.1  mrg 			  "of NO");
   3112      1.1  mrg 	  return;
   3113      1.1  mrg 	}
   3114      1.1  mrg 
   3115      1.1  mrg       if ((cf & IOPARM_DT_HAS_SIZE) != 0
   3116      1.1  mrg 	  && dtp->u.p.advance_status != ADVANCE_NO)
   3117      1.1  mrg 	{
   3118      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
   3119      1.1  mrg 			  "SIZE specification requires an ADVANCE "
   3120      1.1  mrg 			  "specification of NO");
   3121      1.1  mrg 	  return;
   3122      1.1  mrg 	}
   3123      1.1  mrg     }
   3124      1.1  mrg   else
   3125      1.1  mrg     {				/* Write constraints.  */
   3126      1.1  mrg       if ((cf & IOPARM_END) != 0)
   3127      1.1  mrg 	{
   3128      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3129      1.1  mrg 			  "END specification cannot appear in a write "
   3130      1.1  mrg 			  "statement");
   3131      1.1  mrg 	  return;
   3132      1.1  mrg 	}
   3133      1.1  mrg 
   3134      1.1  mrg       if ((cf & IOPARM_EOR) != 0)
   3135      1.1  mrg 	{
   3136      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3137      1.1  mrg 			  "EOR specification cannot appear in a write "
   3138      1.1  mrg 			  "statement");
   3139      1.1  mrg 	  return;
   3140      1.1  mrg 	}
   3141      1.1  mrg 
   3142      1.1  mrg       if ((cf & IOPARM_DT_HAS_SIZE) != 0)
   3143      1.1  mrg 	{
   3144      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3145      1.1  mrg 			  "SIZE specification cannot appear in a write "
   3146      1.1  mrg 			  "statement");
   3147      1.1  mrg 	  return;
   3148      1.1  mrg 	}
   3149      1.1  mrg     }
   3150      1.1  mrg 
   3151      1.1  mrg   if (dtp->u.p.advance_status == ADVANCE_UNSPECIFIED)
   3152      1.1  mrg     dtp->u.p.advance_status = ADVANCE_YES;
   3153      1.1  mrg 
   3154      1.1  mrg   /* Check the decimal mode.  */
   3155      1.1  mrg   dtp->u.p.current_unit->decimal_status
   3156      1.1  mrg 	= !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
   3157      1.1  mrg 	  find_option (&dtp->common, dtp->decimal, dtp->decimal_len,
   3158      1.1  mrg 			decimal_opt, "Bad DECIMAL parameter in data transfer "
   3159      1.1  mrg 			"statement");
   3160      1.1  mrg 
   3161      1.1  mrg   if (dtp->u.p.current_unit->decimal_status == DECIMAL_UNSPECIFIED)
   3162      1.1  mrg 	dtp->u.p.current_unit->decimal_status = dtp->u.p.current_unit->flags.decimal;
   3163      1.1  mrg 
   3164      1.1  mrg   /* Check the round mode.  */
   3165      1.1  mrg   dtp->u.p.current_unit->round_status
   3166      1.1  mrg 	= !(cf & IOPARM_DT_HAS_ROUND) ? ROUND_UNSPECIFIED :
   3167      1.1  mrg 	  find_option (&dtp->common, dtp->round, dtp->round_len,
   3168      1.1  mrg 			round_opt, "Bad ROUND parameter in data transfer "
   3169      1.1  mrg 			"statement");
   3170      1.1  mrg 
   3171      1.1  mrg   if (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED)
   3172      1.1  mrg 	dtp->u.p.current_unit->round_status = dtp->u.p.current_unit->flags.round;
   3173      1.1  mrg 
   3174      1.1  mrg   /* Check the sign mode. */
   3175      1.1  mrg   dtp->u.p.sign_status
   3176      1.1  mrg 	= !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
   3177      1.1  mrg 	  find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt,
   3178      1.1  mrg 			"Bad SIGN parameter in data transfer statement");
   3179      1.1  mrg 
   3180      1.1  mrg   if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
   3181      1.1  mrg 	dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;
   3182      1.1  mrg 
   3183      1.1  mrg   /* Check the blank mode.  */
   3184      1.1  mrg   dtp->u.p.blank_status
   3185      1.1  mrg 	= !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
   3186      1.1  mrg 	  find_option (&dtp->common, dtp->blank, dtp->blank_len,
   3187      1.1  mrg 			blank_opt,
   3188      1.1  mrg 			"Bad BLANK parameter in data transfer statement");
   3189      1.1  mrg 
   3190      1.1  mrg   if (dtp->u.p.blank_status == BLANK_UNSPECIFIED)
   3191      1.1  mrg 	dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;
   3192      1.1  mrg 
   3193      1.1  mrg   /* Check the delim mode.  */
   3194      1.1  mrg   dtp->u.p.current_unit->delim_status
   3195      1.1  mrg 	= !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
   3196      1.1  mrg 	  find_option (&dtp->common, dtp->delim, dtp->delim_len,
   3197      1.1  mrg 	  delim_opt, "Bad DELIM parameter in data transfer statement");
   3198      1.1  mrg 
   3199      1.1  mrg   if (dtp->u.p.current_unit->delim_status == DELIM_UNSPECIFIED)
   3200      1.1  mrg     {
   3201      1.1  mrg       if (ionml && dtp->u.p.current_unit->flags.delim == DELIM_UNSPECIFIED)
   3202      1.1  mrg 	dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
   3203      1.1  mrg       else
   3204      1.1  mrg 	dtp->u.p.current_unit->delim_status = dtp->u.p.current_unit->flags.delim;
   3205      1.1  mrg     }
   3206      1.1  mrg 
   3207      1.1  mrg   /* Check the pad mode.  */
   3208      1.1  mrg   dtp->u.p.current_unit->pad_status
   3209      1.1  mrg 	= !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
   3210      1.1  mrg 	  find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt,
   3211      1.1  mrg 			"Bad PAD parameter in data transfer statement");
   3212      1.1  mrg 
   3213      1.1  mrg   if (dtp->u.p.current_unit->pad_status == PAD_UNSPECIFIED)
   3214      1.1  mrg 	dtp->u.p.current_unit->pad_status = dtp->u.p.current_unit->flags.pad;
   3215      1.1  mrg 
   3216      1.1  mrg   /* Set up the subroutine that will handle the transfers.  */
   3217      1.1  mrg 
   3218      1.1  mrg   if (read_flag)
   3219      1.1  mrg     {
   3220      1.1  mrg       if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   3221      1.1  mrg 	dtp->u.p.transfer = unformatted_read;
   3222      1.1  mrg       else
   3223      1.1  mrg 	{
   3224      1.1  mrg 	  if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
   3225      1.1  mrg 	    dtp->u.p.transfer = list_formatted_read;
   3226      1.1  mrg 	  else
   3227      1.1  mrg 	    dtp->u.p.transfer = formatted_transfer;
   3228      1.1  mrg 	}
   3229      1.1  mrg     }
   3230      1.1  mrg   else
   3231      1.1  mrg     {
   3232      1.1  mrg       if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
   3233      1.1  mrg 	dtp->u.p.transfer = unformatted_write;
   3234      1.1  mrg       else
   3235      1.1  mrg 	{
   3236      1.1  mrg 	  if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
   3237      1.1  mrg 	    dtp->u.p.transfer = list_formatted_write;
   3238      1.1  mrg 	  else
   3239      1.1  mrg 	    dtp->u.p.transfer = formatted_transfer;
   3240      1.1  mrg 	}
   3241      1.1  mrg     }
   3242      1.1  mrg 
   3243      1.1  mrg   if (au && dtp->u.p.async)
   3244      1.1  mrg     {
   3245      1.1  mrg       NOTE ("enqueue_data_transfer");
   3246      1.1  mrg       enqueue_data_transfer_init (au, dtp, read_flag);
   3247      1.1  mrg     }
   3248      1.1  mrg   else
   3249      1.1  mrg     {
   3250      1.1  mrg       NOTE ("invoking data_transfer_init_worker");
   3251      1.1  mrg       data_transfer_init_worker (dtp, read_flag);
   3252      1.1  mrg     }
   3253      1.1  mrg }
   3254      1.1  mrg 
   3255      1.1  mrg void
   3256      1.1  mrg data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
   3257      1.1  mrg {
   3258      1.1  mrg   GFC_INTEGER_4 cf = dtp->common.flags;
   3259      1.1  mrg 
   3260      1.1  mrg   NOTE ("starting worker...");
   3261      1.1  mrg 
   3262      1.1  mrg   if (read_flag && dtp->u.p.current_unit->flags.form != FORM_UNFORMATTED
   3263      1.1  mrg       && ((cf & IOPARM_DT_LIST_FORMAT) != 0)
   3264      1.1  mrg       && dtp->u.p.current_unit->child_dtio  == 0)
   3265      1.1  mrg     dtp->u.p.current_unit->last_char = EOF - 1;
   3266      1.1  mrg 
   3267      1.1  mrg   /* Check to see if we might be reading what we wrote before  */
   3268      1.1  mrg 
   3269      1.1  mrg   if (dtp->u.p.mode != dtp->u.p.current_unit->mode
   3270      1.1  mrg       && !is_internal_unit (dtp))
   3271      1.1  mrg     {
   3272      1.1  mrg       int pos = fbuf_reset (dtp->u.p.current_unit);
   3273      1.1  mrg       if (pos != 0)
   3274      1.1  mrg         sseek (dtp->u.p.current_unit->s, pos, SEEK_CUR);
   3275      1.1  mrg       sflush(dtp->u.p.current_unit->s);
   3276      1.1  mrg     }
   3277      1.1  mrg 
   3278      1.1  mrg   /* Check the POS= specifier: that it is in range and that it is used with a
   3279      1.1  mrg      unit that has been connected for STREAM access. F2003 9.5.1.10.  */
   3280      1.1  mrg 
   3281      1.1  mrg   if (((cf & IOPARM_DT_HAS_POS) != 0))
   3282      1.1  mrg     {
   3283      1.1  mrg       if (is_stream_io (dtp))
   3284      1.1  mrg         {
   3285      1.1  mrg 
   3286      1.1  mrg           if (dtp->pos <= 0)
   3287      1.1  mrg             {
   3288      1.1  mrg               generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3289      1.1  mrg                               "POS=specifier must be positive");
   3290      1.1  mrg               return;
   3291      1.1  mrg             }
   3292      1.1  mrg 
   3293      1.1  mrg           if (dtp->pos >= dtp->u.p.current_unit->maxrec)
   3294      1.1  mrg             {
   3295      1.1  mrg               generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3296      1.1  mrg                               "POS=specifier too large");
   3297      1.1  mrg               return;
   3298      1.1  mrg             }
   3299      1.1  mrg 
   3300      1.1  mrg           dtp->rec = dtp->pos;
   3301      1.1  mrg 
   3302      1.1  mrg           if (dtp->u.p.mode == READING)
   3303      1.1  mrg             {
   3304      1.1  mrg               /* Reset the endfile flag; if we hit EOF during reading
   3305      1.1  mrg                  we'll set the flag and generate an error at that point
   3306      1.1  mrg                  rather than worrying about it here.  */
   3307      1.1  mrg               dtp->u.p.current_unit->endfile = NO_ENDFILE;
   3308      1.1  mrg             }
   3309      1.1  mrg 
   3310      1.1  mrg           if (dtp->pos != dtp->u.p.current_unit->strm_pos)
   3311      1.1  mrg             {
   3312  1.1.1.2  mrg 	      fbuf_reset (dtp->u.p.current_unit);
   3313  1.1.1.2  mrg 	      if (sseek (dtp->u.p.current_unit->s, dtp->pos - 1,
   3314  1.1.1.2  mrg 			 SEEK_SET) < 0)
   3315      1.1  mrg                 {
   3316      1.1  mrg                   generate_error (&dtp->common, LIBERROR_OS, NULL);
   3317      1.1  mrg                   return;
   3318      1.1  mrg                 }
   3319      1.1  mrg               dtp->u.p.current_unit->strm_pos = dtp->pos;
   3320      1.1  mrg             }
   3321      1.1  mrg         }
   3322      1.1  mrg       else
   3323      1.1  mrg         {
   3324      1.1  mrg           generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3325      1.1  mrg                           "POS=specifier not allowed, "
   3326      1.1  mrg                           "Try OPEN with ACCESS='stream'");
   3327      1.1  mrg           return;
   3328      1.1  mrg         }
   3329      1.1  mrg     }
   3330      1.1  mrg 
   3331      1.1  mrg 
   3332      1.1  mrg   /* Sanity checks on the record number.  */
   3333      1.1  mrg   if ((cf & IOPARM_DT_HAS_REC) != 0)
   3334      1.1  mrg     {
   3335      1.1  mrg       if (dtp->rec <= 0)
   3336      1.1  mrg 	{
   3337      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3338      1.1  mrg 			  "Record number must be positive");
   3339      1.1  mrg 	  return;
   3340      1.1  mrg 	}
   3341      1.1  mrg 
   3342      1.1  mrg       if (dtp->rec >= dtp->u.p.current_unit->maxrec)
   3343      1.1  mrg 	{
   3344      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3345      1.1  mrg 			  "Record number too large");
   3346      1.1  mrg 	  return;
   3347      1.1  mrg 	}
   3348      1.1  mrg 
   3349      1.1  mrg       /* Make sure format buffer is reset.  */
   3350      1.1  mrg       if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
   3351      1.1  mrg         fbuf_reset (dtp->u.p.current_unit);
   3352      1.1  mrg 
   3353      1.1  mrg 
   3354      1.1  mrg       /* Check whether the record exists to be read.  Only
   3355      1.1  mrg 	 a partial record needs to exist.  */
   3356      1.1  mrg 
   3357      1.1  mrg       if (dtp->u.p.mode == READING && (dtp->rec - 1)
   3358      1.1  mrg 	  * dtp->u.p.current_unit->recl >= ssize (dtp->u.p.current_unit->s))
   3359      1.1  mrg 	{
   3360      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3361      1.1  mrg 			  "Non-existing record number");
   3362      1.1  mrg 	  return;
   3363      1.1  mrg 	}
   3364      1.1  mrg 
   3365      1.1  mrg       /* Position the file.  */
   3366      1.1  mrg       if (sseek (dtp->u.p.current_unit->s, (gfc_offset) (dtp->rec - 1)
   3367      1.1  mrg 		 * dtp->u.p.current_unit->recl, SEEK_SET) < 0)
   3368      1.1  mrg 	{
   3369      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_OS, NULL);
   3370      1.1  mrg 	  return;
   3371      1.1  mrg 	}
   3372      1.1  mrg 
   3373      1.1  mrg       if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
   3374      1.1  mrg        {
   3375      1.1  mrg          generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
   3376      1.1  mrg                      "Record number not allowed for stream access "
   3377      1.1  mrg                      "data transfer");
   3378      1.1  mrg          return;
   3379      1.1  mrg        }
   3380      1.1  mrg     }
   3381      1.1  mrg 
   3382      1.1  mrg   /* Bugware for badly written mixed C-Fortran I/O.  */
   3383      1.1  mrg   if (!is_internal_unit (dtp))
   3384      1.1  mrg     flush_if_preconnected(dtp->u.p.current_unit->s);
   3385      1.1  mrg 
   3386      1.1  mrg   dtp->u.p.current_unit->mode = dtp->u.p.mode;
   3387      1.1  mrg 
   3388      1.1  mrg   /* Set the maximum position reached from the previous I/O operation.  This
   3389      1.1  mrg      could be greater than zero from a previous non-advancing write.  */
   3390      1.1  mrg   dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
   3391      1.1  mrg 
   3392      1.1  mrg   pre_position (dtp);
   3393      1.1  mrg 
   3394      1.1  mrg   /* Make sure that we don't do a read after a nonadvancing write.  */
   3395      1.1  mrg 
   3396      1.1  mrg   if (read_flag)
   3397      1.1  mrg     {
   3398      1.1  mrg       if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
   3399      1.1  mrg 	{
   3400      1.1  mrg 	  generate_error (&dtp->common, LIBERROR_BAD_OPTION,
   3401      1.1  mrg 			  "Cannot READ after a nonadvancing WRITE");
   3402      1.1  mrg 	  return;
   3403      1.1  mrg 	}
   3404      1.1  mrg     }
   3405      1.1  mrg   else
   3406      1.1  mrg     {
   3407      1.1  mrg       if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
   3408      1.1  mrg 	dtp->u.p.current_unit->read_bad = 1;
   3409      1.1  mrg     }
   3410      1.1  mrg 
   3411      1.1  mrg   if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
   3412      1.1  mrg     {
   3413      1.1  mrg #ifdef HAVE_USELOCALE
   3414      1.1  mrg       dtp->u.p.old_locale = uselocale (c_locale);
   3415      1.1  mrg #else
   3416      1.1  mrg       __gthread_mutex_lock (&old_locale_lock);
   3417      1.1  mrg       if (!old_locale_ctr++)
   3418      1.1  mrg 	{
   3419      1.1  mrg 	  old_locale = setlocale (LC_NUMERIC, NULL);
   3420      1.1  mrg 	  setlocale (LC_NUMERIC, "C");
   3421      1.1  mrg 	}
   3422      1.1  mrg       __gthread_mutex_unlock (&old_locale_lock);
   3423      1.1  mrg #endif
   3424      1.1  mrg       /* Start the data transfer if we are doing a formatted transfer.  */
   3425      1.1  mrg       if ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0
   3426      1.1  mrg 	&& dtp->u.p.ionml == NULL)
   3427      1.1  mrg 	formatted_transfer (dtp, 0, NULL, 0, 0, 1);
   3428      1.1  mrg     }
   3429      1.1  mrg }
   3430      1.1  mrg 
   3431      1.1  mrg 
   3432      1.1  mrg /* Initialize an array_loop_spec given the array descriptor.  The function
   3433      1.1  mrg    returns the index of the last element of the array, and also returns
   3434      1.1  mrg    starting record, where the first I/O goes to (necessary in case of
   3435      1.1  mrg    negative strides).  */
   3436      1.1  mrg 
   3437      1.1  mrg gfc_offset
   3438      1.1  mrg init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
   3439      1.1  mrg 		gfc_offset *start_record)
   3440      1.1  mrg {
   3441      1.1  mrg   int rank = GFC_DESCRIPTOR_RANK(desc);
   3442      1.1  mrg   int i;
   3443      1.1  mrg   gfc_offset index;
   3444      1.1  mrg   int empty;
   3445      1.1  mrg 
   3446      1.1  mrg   empty = 0;
   3447      1.1  mrg   index = 1;
   3448      1.1  mrg   *start_record = 0;
   3449      1.1  mrg 
   3450      1.1  mrg   for (i=0; i<rank; i++)
   3451      1.1  mrg     {
   3452      1.1  mrg       ls[i].idx = GFC_DESCRIPTOR_LBOUND(desc,i);
   3453      1.1  mrg       ls[i].start = GFC_DESCRIPTOR_LBOUND(desc,i);
   3454      1.1  mrg       ls[i].end = GFC_DESCRIPTOR_UBOUND(desc,i);
   3455      1.1  mrg       ls[i].step = GFC_DESCRIPTOR_STRIDE(desc,i);
   3456      1.1  mrg       empty = empty || (GFC_DESCRIPTOR_UBOUND(desc,i)
   3457      1.1  mrg 			< GFC_DESCRIPTOR_LBOUND(desc,i));
   3458      1.1  mrg 
   3459      1.1  mrg       if (GFC_DESCRIPTOR_STRIDE(desc,i) > 0)
   3460      1.1  mrg 	{
   3461      1.1  mrg 	  index += (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
   3462      1.1  mrg 	    * GFC_DESCRIPTOR_STRIDE(desc,i);
   3463      1.1  mrg 	}
   3464      1.1  mrg       else
   3465      1.1  mrg 	{
   3466      1.1  mrg 	  index -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
   3467      1.1  mrg 	    * GFC_DESCRIPTOR_STRIDE(desc,i);
   3468      1.1  mrg 	  *start_record -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
   3469      1.1  mrg 	    * GFC_DESCRIPTOR_STRIDE(desc,i);
   3470      1.1  mrg 	}
   3471      1.1  mrg     }
   3472      1.1  mrg 
   3473      1.1  mrg   if (empty)
   3474      1.1  mrg     return 0;
   3475      1.1  mrg   else
   3476      1.1  mrg     return index;
   3477      1.1  mrg }
   3478      1.1  mrg 
   3479      1.1  mrg /* Determine the index to the next record in an internal unit array by
   3480      1.1  mrg    by incrementing through the array_loop_spec.  */
   3481      1.1  mrg 
   3482      1.1  mrg gfc_offset
   3483      1.1  mrg next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
   3484      1.1  mrg {
   3485      1.1  mrg   int i, carry;
   3486      1.1  mrg   gfc_offset index;
   3487      1.1  mrg 
   3488      1.1  mrg   carry = 1;
   3489      1.1  mrg   index = 0;
   3490      1.1  mrg 
   3491      1.1  mrg   for (i = 0; i < dtp->u.p.current_unit->rank; i++)
   3492      1.1  mrg     {
   3493      1.1  mrg       if (carry)
   3494      1.1  mrg         {
   3495      1.1  mrg           ls[i].idx++;
   3496      1.1  mrg           if (ls[i].idx > ls[i].end)
   3497      1.1  mrg             {
   3498      1.1  mrg               ls[i].idx = ls[i].start;
   3499      1.1  mrg               carry = 1;
   3500      1.1  mrg             }
   3501      1.1  mrg           else
   3502      1.1  mrg             carry = 0;
   3503      1.1  mrg         }
   3504      1.1  mrg       index = index + (ls[i].idx - ls[i].start) * ls[i].step;
   3505      1.1  mrg     }
   3506      1.1  mrg 
   3507      1.1  mrg   *finished = carry;
   3508      1.1  mrg 
   3509      1.1  mrg   return index;
   3510      1.1  mrg }
   3511      1.1  mrg 
   3512      1.1  mrg 
   3513      1.1  mrg 
   3514      1.1  mrg /* Skip to the end of the current record, taking care of an optional
   3515      1.1  mrg    record marker of size bytes.  If the file is not seekable, we
   3516      1.1  mrg    read chunks of size MAX_READ until we get to the right
   3517      1.1  mrg    position.  */
   3518      1.1  mrg 
   3519      1.1  mrg static void
   3520      1.1  mrg skip_record (st_parameter_dt *dtp, gfc_offset bytes)
   3521      1.1  mrg {
   3522      1.1  mrg   ssize_t rlength, readb;
   3523      1.1  mrg #define MAX_READ 4096
   3524      1.1  mrg   char p[MAX_READ];
   3525      1.1  mrg 
   3526      1.1  mrg   dtp->u.p.current_unit->bytes_left_subrecord += bytes;
   3527      1.1  mrg   if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
   3528      1.1  mrg     return;
   3529      1.1  mrg 
   3530      1.1  mrg   /* Direct access files do not generate END conditions,
   3531      1.1  mrg      only I/O errors.  */
   3532      1.1  mrg   if (sseek (dtp->u.p.current_unit->s,
   3533      1.1  mrg 	     dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
   3534      1.1  mrg     {
   3535      1.1  mrg       /* Seeking failed, fall back to seeking by reading data.  */
   3536      1.1  mrg       while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
   3537      1.1  mrg 	{
   3538      1.1  mrg 	  rlength =
   3539      1.1  mrg 	    (MAX_READ < dtp->u.p.current_unit->bytes_left_subrecord) ?
   3540      1.1  mrg 	    MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
   3541      1.1  mrg 
   3542      1.1  mrg 	  readb = sread (dtp->u.p.current_unit->s, p, rlength);
   3543      1.1  mrg 	  if (readb < 0)
   3544      1.1  mrg 	    {
   3545      1.1  mrg 	      generate_error (&dtp->common, LIBERROR_OS, NULL);
   3546      1.1  mrg 	      return;
   3547      1.1  mrg 	    }
   3548      1.1  mrg 
   3549      1.1  mrg 	  dtp->u.p.current_unit->bytes_left_subrecord -= readb;
   3550      1.1  mrg 	}
   3551      1.1  mrg       return;
   3552      1.1  mrg     }
   3553      1.1  mrg   dtp->u.p.current_unit->bytes_left_subrecord = 0;
   3554      1.1  mrg }
   3555      1.1  mrg 
   3556      1.1  mrg 
   3557      1.1  mrg /* Advance to the next record reading unformatted files, taking
   3558      1.1  mrg    care of subrecords.  If complete_record is nonzero, we loop
   3559      1.1  mrg    until all subrecords are cleared.  */
   3560      1.1  mrg 
   3561      1.1  mrg static void
   3562      1.1  mrg next_record_r_unf (st_parameter_dt *dtp, int complete_record)
   3563      1.1  mrg {
   3564      1.1  mrg   size_t bytes;
   3565      1.1  mrg 
   3566      1.1  mrg   bytes =  compile_options.record_marker == 0 ?
   3567      1.1  mrg     sizeof (GFC_INTEGER_4) : compile_options.record_marker;
   3568      1.1  mrg 
   3569      1.1  mrg   while(1)
   3570      1.1  mrg     {
   3571      1.1  mrg 
   3572      1.1  mrg       /* Skip over tail */
   3573      1.1  mrg 
   3574      1.1  mrg       skip_record (dtp, bytes);
   3575      1.1  mrg 
   3576      1.1  mrg       if ( ! (complete_record && dtp->u.p.current_unit->continued))
   3577      1.1  mrg 	return;
   3578      1.1  mrg 
   3579      1.1  mrg       us_read (dtp, 1);
   3580      1.1  mrg     }
   3581      1.1  mrg }
   3582      1.1  mrg 
   3583      1.1  mrg 
   3584      1.1  mrg static gfc_offset
   3585      1.1  mrg min_off (gfc_offset a, gfc_offset b)
   3586      1.1  mrg {
   3587      1.1  mrg   return (a < b ? a : b);
   3588      1.1  mrg }
   3589      1.1  mrg 
   3590      1.1  mrg 
   3591      1.1  mrg /* Space to the next record for read mode.  */
   3592      1.1  mrg 
   3593      1.1  mrg static void
   3594      1.1  mrg next_record_r (st_parameter_dt *dtp, int done)
   3595      1.1  mrg {
   3596      1.1  mrg   gfc_offset record;
   3597      1.1  mrg   char p;
   3598      1.1  mrg   int cc;
   3599      1.1  mrg 
   3600      1.1  mrg   switch (current_mode (dtp))
   3601      1.1  mrg     {
   3602      1.1  mrg     /* No records in unformatted STREAM I/O.  */
   3603      1.1  mrg     case UNFORMATTED_STREAM:
   3604      1.1  mrg       return;
   3605      1.1  mrg 
   3606      1.1  mrg     case UNFORMATTED_SEQUENTIAL:
   3607      1.1  mrg       next_record_r_unf (dtp, 1);
   3608      1.1  mrg       dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3609      1.1  mrg       break;
   3610      1.1  mrg 
   3611      1.1  mrg     case FORMATTED_DIRECT:
   3612      1.1  mrg     case UNFORMATTED_DIRECT:
   3613      1.1  mrg       skip_record (dtp, dtp->u.p.current_unit->bytes_left);
   3614      1.1  mrg       break;
   3615      1.1  mrg 
   3616      1.1  mrg     case FORMATTED_STREAM:
   3617      1.1  mrg     case FORMATTED_SEQUENTIAL:
   3618      1.1  mrg       /* read_sf has already terminated input because of an '\n', or
   3619      1.1  mrg          we have hit EOF.  */
   3620      1.1  mrg       if (dtp->u.p.sf_seen_eor)
   3621      1.1  mrg 	{
   3622      1.1  mrg 	  dtp->u.p.sf_seen_eor = 0;
   3623      1.1  mrg 	  break;
   3624      1.1  mrg 	}
   3625      1.1  mrg 
   3626      1.1  mrg       if (is_internal_unit (dtp))
   3627      1.1  mrg 	{
   3628      1.1  mrg 	  if (is_array_io (dtp))
   3629      1.1  mrg 	    {
   3630      1.1  mrg 	      int finished;
   3631      1.1  mrg 
   3632      1.1  mrg 	      record = next_array_record (dtp, dtp->u.p.current_unit->ls,
   3633      1.1  mrg 					  &finished);
   3634      1.1  mrg 	      if (!done && finished)
   3635      1.1  mrg 		hit_eof (dtp);
   3636      1.1  mrg 
   3637      1.1  mrg 	      /* Now seek to this record.  */
   3638      1.1  mrg 	      record = record * dtp->u.p.current_unit->recl;
   3639      1.1  mrg 	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
   3640      1.1  mrg 		{
   3641      1.1  mrg 		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3642      1.1  mrg 		  break;
   3643      1.1  mrg 		}
   3644      1.1  mrg 	      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3645      1.1  mrg 	    }
   3646      1.1  mrg 	  else
   3647      1.1  mrg 	    {
   3648      1.1  mrg 	      gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
   3649      1.1  mrg 	      bytes_left = min_off (bytes_left,
   3650      1.1  mrg 		      ssize (dtp->u.p.current_unit->s)
   3651      1.1  mrg 		      - stell (dtp->u.p.current_unit->s));
   3652      1.1  mrg 	      if (sseek (dtp->u.p.current_unit->s,
   3653      1.1  mrg 			 bytes_left, SEEK_CUR) < 0)
   3654      1.1  mrg 	        {
   3655      1.1  mrg 		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3656      1.1  mrg 		  break;
   3657      1.1  mrg 		}
   3658      1.1  mrg 	      dtp->u.p.current_unit->bytes_left
   3659      1.1  mrg 		= dtp->u.p.current_unit->recl;
   3660      1.1  mrg 	    }
   3661      1.1  mrg 	  break;
   3662      1.1  mrg 	}
   3663      1.1  mrg       else if (dtp->u.p.current_unit->flags.cc != CC_NONE)
   3664      1.1  mrg 	{
   3665      1.1  mrg 	  do
   3666      1.1  mrg 	    {
   3667      1.1  mrg               errno = 0;
   3668      1.1  mrg               cc = fbuf_getc (dtp->u.p.current_unit);
   3669      1.1  mrg 	      if (cc == EOF)
   3670      1.1  mrg 		{
   3671      1.1  mrg                   if (errno != 0)
   3672      1.1  mrg                     generate_error (&dtp->common, LIBERROR_OS, NULL);
   3673      1.1  mrg 		  else
   3674      1.1  mrg 		    {
   3675      1.1  mrg 		      if (is_stream_io (dtp)
   3676      1.1  mrg 			  || dtp->u.p.current_unit->pad_status == PAD_NO
   3677      1.1  mrg 			  || dtp->u.p.current_unit->bytes_left
   3678      1.1  mrg 			     == dtp->u.p.current_unit->recl)
   3679      1.1  mrg 			hit_eof (dtp);
   3680      1.1  mrg 		    }
   3681      1.1  mrg 		  break;
   3682      1.1  mrg                 }
   3683      1.1  mrg 
   3684      1.1  mrg 	      if (is_stream_io (dtp))
   3685      1.1  mrg 		dtp->u.p.current_unit->strm_pos++;
   3686      1.1  mrg 
   3687      1.1  mrg               p = (char) cc;
   3688      1.1  mrg 	    }
   3689      1.1  mrg 	  while (p != '\n');
   3690      1.1  mrg 	}
   3691      1.1  mrg       break;
   3692  1.1.1.2  mrg     case FORMATTED_UNSPECIFIED:
   3693  1.1.1.2  mrg       gcc_unreachable ();
   3694      1.1  mrg     }
   3695      1.1  mrg }
   3696      1.1  mrg 
   3697      1.1  mrg 
   3698      1.1  mrg /* Small utility function to write a record marker, taking care of
   3699      1.1  mrg    byte swapping and of choosing the correct size.  */
   3700      1.1  mrg 
   3701      1.1  mrg static int
   3702      1.1  mrg write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
   3703      1.1  mrg {
   3704      1.1  mrg   size_t len;
   3705      1.1  mrg   GFC_INTEGER_4 buf4;
   3706      1.1  mrg   GFC_INTEGER_8 buf8;
   3707      1.1  mrg 
   3708      1.1  mrg   if (compile_options.record_marker == 0)
   3709      1.1  mrg     len = sizeof (GFC_INTEGER_4);
   3710      1.1  mrg   else
   3711      1.1  mrg     len = compile_options.record_marker;
   3712      1.1  mrg 
   3713      1.1  mrg   /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here.  */
   3714      1.1  mrg   if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
   3715      1.1  mrg     {
   3716      1.1  mrg       switch (len)
   3717      1.1  mrg 	{
   3718      1.1  mrg 	case sizeof (GFC_INTEGER_4):
   3719      1.1  mrg 	  buf4 = buf;
   3720      1.1  mrg 	  return swrite (dtp->u.p.current_unit->s, &buf4, len);
   3721      1.1  mrg 	  break;
   3722      1.1  mrg 
   3723      1.1  mrg 	case sizeof (GFC_INTEGER_8):
   3724      1.1  mrg 	  buf8 = buf;
   3725      1.1  mrg 	  return swrite (dtp->u.p.current_unit->s, &buf8, len);
   3726      1.1  mrg 	  break;
   3727      1.1  mrg 
   3728      1.1  mrg 	default:
   3729      1.1  mrg 	  runtime_error ("Illegal value for record marker");
   3730      1.1  mrg 	  break;
   3731      1.1  mrg 	}
   3732      1.1  mrg     }
   3733      1.1  mrg   else
   3734      1.1  mrg     {
   3735      1.1  mrg       uint32_t u32;
   3736      1.1  mrg       uint64_t u64;
   3737      1.1  mrg       switch (len)
   3738      1.1  mrg 	{
   3739      1.1  mrg 	case sizeof (GFC_INTEGER_4):
   3740      1.1  mrg 	  buf4 = buf;
   3741      1.1  mrg 	  memcpy (&u32, &buf4, sizeof (u32));
   3742      1.1  mrg 	  u32 = __builtin_bswap32 (u32);
   3743      1.1  mrg 	  return swrite (dtp->u.p.current_unit->s, &u32, len);
   3744      1.1  mrg 	  break;
   3745      1.1  mrg 
   3746      1.1  mrg 	case sizeof (GFC_INTEGER_8):
   3747      1.1  mrg 	  buf8 = buf;
   3748      1.1  mrg 	  memcpy (&u64, &buf8, sizeof (u64));
   3749      1.1  mrg 	  u64 = __builtin_bswap64 (u64);
   3750      1.1  mrg 	  return swrite (dtp->u.p.current_unit->s, &u64, len);
   3751      1.1  mrg 	  break;
   3752      1.1  mrg 
   3753      1.1  mrg 	default:
   3754      1.1  mrg 	  runtime_error ("Illegal value for record marker");
   3755      1.1  mrg 	  break;
   3756      1.1  mrg 	}
   3757      1.1  mrg     }
   3758      1.1  mrg 
   3759      1.1  mrg }
   3760      1.1  mrg 
   3761      1.1  mrg /* Position to the next (sub)record in write mode for
   3762      1.1  mrg    unformatted sequential files.  */
   3763      1.1  mrg 
   3764      1.1  mrg static void
   3765      1.1  mrg next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
   3766      1.1  mrg {
   3767      1.1  mrg   gfc_offset m, m_write, record_marker;
   3768      1.1  mrg 
   3769      1.1  mrg   /* Bytes written.  */
   3770      1.1  mrg   m = dtp->u.p.current_unit->recl_subrecord
   3771      1.1  mrg     - dtp->u.p.current_unit->bytes_left_subrecord;
   3772      1.1  mrg 
   3773      1.1  mrg   if (compile_options.record_marker == 0)
   3774      1.1  mrg     record_marker = sizeof (GFC_INTEGER_4);
   3775      1.1  mrg   else
   3776      1.1  mrg     record_marker = compile_options.record_marker;
   3777      1.1  mrg 
   3778      1.1  mrg   /* Seek to the head and overwrite the bogus length with the real
   3779      1.1  mrg      length.  */
   3780      1.1  mrg 
   3781      1.1  mrg   if (unlikely (sseek (dtp->u.p.current_unit->s, - m - record_marker,
   3782      1.1  mrg 		       SEEK_CUR) < 0))
   3783      1.1  mrg     goto io_error;
   3784      1.1  mrg 
   3785      1.1  mrg   if (next_subrecord)
   3786      1.1  mrg     m_write = -m;
   3787      1.1  mrg   else
   3788      1.1  mrg     m_write = m;
   3789      1.1  mrg 
   3790      1.1  mrg   if (unlikely (write_us_marker (dtp, m_write) < 0))
   3791      1.1  mrg     goto io_error;
   3792      1.1  mrg 
   3793      1.1  mrg   /* Seek past the end of the current record.  */
   3794      1.1  mrg 
   3795      1.1  mrg   if (unlikely (sseek (dtp->u.p.current_unit->s, m, SEEK_CUR) < 0))
   3796      1.1  mrg     goto io_error;
   3797      1.1  mrg 
   3798      1.1  mrg   /* Write the length tail.  If we finish a record containing
   3799      1.1  mrg      subrecords, we write out the negative length.  */
   3800      1.1  mrg 
   3801      1.1  mrg   if (dtp->u.p.current_unit->continued)
   3802      1.1  mrg     m_write = -m;
   3803      1.1  mrg   else
   3804      1.1  mrg     m_write = m;
   3805      1.1  mrg 
   3806      1.1  mrg   if (unlikely (write_us_marker (dtp, m_write) < 0))
   3807      1.1  mrg     goto io_error;
   3808      1.1  mrg 
   3809      1.1  mrg   return;
   3810      1.1  mrg 
   3811      1.1  mrg  io_error:
   3812      1.1  mrg   generate_error (&dtp->common, LIBERROR_OS, NULL);
   3813      1.1  mrg   return;
   3814      1.1  mrg 
   3815      1.1  mrg }
   3816      1.1  mrg 
   3817      1.1  mrg 
   3818      1.1  mrg /* Utility function like memset() but operating on streams. Return
   3819      1.1  mrg    value is same as for POSIX write().  */
   3820      1.1  mrg 
   3821      1.1  mrg static gfc_offset
   3822      1.1  mrg sset (stream *s, int c, gfc_offset nbyte)
   3823      1.1  mrg {
   3824      1.1  mrg #define WRITE_CHUNK 256
   3825      1.1  mrg   char p[WRITE_CHUNK];
   3826      1.1  mrg   gfc_offset bytes_left;
   3827      1.1  mrg   ssize_t trans;
   3828      1.1  mrg 
   3829      1.1  mrg   if (nbyte < WRITE_CHUNK)
   3830      1.1  mrg     memset (p, c, nbyte);
   3831      1.1  mrg   else
   3832      1.1  mrg     memset (p, c, WRITE_CHUNK);
   3833      1.1  mrg 
   3834      1.1  mrg   bytes_left = nbyte;
   3835      1.1  mrg   while (bytes_left > 0)
   3836      1.1  mrg     {
   3837      1.1  mrg       trans = (bytes_left < WRITE_CHUNK) ? bytes_left : WRITE_CHUNK;
   3838      1.1  mrg       trans = swrite (s, p, trans);
   3839      1.1  mrg       if (trans <= 0)
   3840      1.1  mrg 	return trans;
   3841      1.1  mrg       bytes_left -= trans;
   3842      1.1  mrg     }
   3843      1.1  mrg 
   3844      1.1  mrg   return nbyte - bytes_left;
   3845      1.1  mrg }
   3846      1.1  mrg 
   3847      1.1  mrg 
   3848      1.1  mrg /* Finish up a record according to the legacy carriagecontrol type, based
   3849      1.1  mrg    on the first character in the record.  */
   3850      1.1  mrg 
   3851      1.1  mrg static void
   3852      1.1  mrg next_record_cc (st_parameter_dt *dtp)
   3853      1.1  mrg {
   3854      1.1  mrg   /* Only valid with CARRIAGECONTROL=FORTRAN.  */
   3855      1.1  mrg   if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
   3856      1.1  mrg     return;
   3857      1.1  mrg 
   3858      1.1  mrg   fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   3859      1.1  mrg   if (dtp->u.p.cc.len > 0)
   3860      1.1  mrg     {
   3861      1.1  mrg       char *p = fbuf_alloc (dtp->u.p.current_unit, dtp->u.p.cc.len);
   3862      1.1  mrg       if (!p)
   3863      1.1  mrg 	generate_error (&dtp->common, LIBERROR_OS, NULL);
   3864      1.1  mrg 
   3865      1.1  mrg       /* Output CR for the first character with default CC setting.  */
   3866      1.1  mrg       *(p++) = dtp->u.p.cc.u.end;
   3867      1.1  mrg       if (dtp->u.p.cc.len > 1)
   3868      1.1  mrg 	*p = dtp->u.p.cc.u.end;
   3869      1.1  mrg     }
   3870      1.1  mrg }
   3871      1.1  mrg 
   3872      1.1  mrg /* Position to the next record in write mode.  */
   3873      1.1  mrg 
   3874      1.1  mrg static void
   3875      1.1  mrg next_record_w (st_parameter_dt *dtp, int done)
   3876      1.1  mrg {
   3877      1.1  mrg   gfc_offset max_pos_off;
   3878      1.1  mrg 
   3879      1.1  mrg   /* Zero counters for X- and T-editing.  */
   3880      1.1  mrg   max_pos_off = dtp->u.p.max_pos;
   3881      1.1  mrg   dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
   3882      1.1  mrg 
   3883      1.1  mrg   switch (current_mode (dtp))
   3884      1.1  mrg     {
   3885      1.1  mrg     /* No records in unformatted STREAM I/O.  */
   3886      1.1  mrg     case UNFORMATTED_STREAM:
   3887      1.1  mrg       return;
   3888      1.1  mrg 
   3889      1.1  mrg     case FORMATTED_DIRECT:
   3890      1.1  mrg       if (dtp->u.p.current_unit->bytes_left == 0)
   3891      1.1  mrg 	break;
   3892      1.1  mrg 
   3893      1.1  mrg       fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   3894      1.1  mrg       fbuf_flush (dtp->u.p.current_unit, WRITING);
   3895      1.1  mrg       if (sset (dtp->u.p.current_unit->s, ' ',
   3896      1.1  mrg 		dtp->u.p.current_unit->bytes_left)
   3897      1.1  mrg 	  != dtp->u.p.current_unit->bytes_left)
   3898      1.1  mrg 	goto io_error;
   3899      1.1  mrg 
   3900      1.1  mrg       break;
   3901      1.1  mrg 
   3902      1.1  mrg     case UNFORMATTED_DIRECT:
   3903      1.1  mrg       if (dtp->u.p.current_unit->bytes_left > 0)
   3904      1.1  mrg 	{
   3905      1.1  mrg 	  gfc_offset length = dtp->u.p.current_unit->bytes_left;
   3906      1.1  mrg 	  if (sset (dtp->u.p.current_unit->s, 0, length) != length)
   3907      1.1  mrg 	    goto io_error;
   3908      1.1  mrg 	}
   3909      1.1  mrg       break;
   3910      1.1  mrg 
   3911      1.1  mrg     case UNFORMATTED_SEQUENTIAL:
   3912      1.1  mrg       next_record_w_unf (dtp, 0);
   3913      1.1  mrg       dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3914      1.1  mrg       break;
   3915      1.1  mrg 
   3916      1.1  mrg     case FORMATTED_STREAM:
   3917      1.1  mrg     case FORMATTED_SEQUENTIAL:
   3918      1.1  mrg 
   3919      1.1  mrg       if (is_internal_unit (dtp))
   3920      1.1  mrg 	{
   3921      1.1  mrg 	  char *p;
   3922      1.1  mrg 	  /* Internal unit, so must fit in memory.  */
   3923      1.1  mrg 	  size_t length, m;
   3924      1.1  mrg 	  size_t max_pos = max_pos_off;
   3925      1.1  mrg 	  if (is_array_io (dtp))
   3926      1.1  mrg 	    {
   3927      1.1  mrg 	      int finished;
   3928      1.1  mrg 
   3929      1.1  mrg 	      length = dtp->u.p.current_unit->bytes_left;
   3930      1.1  mrg 
   3931      1.1  mrg 	      /* If the farthest position reached is greater than current
   3932      1.1  mrg 	      position, adjust the position and set length to pad out
   3933      1.1  mrg 	      whats left.  Otherwise just pad whats left.
   3934      1.1  mrg 	      (for character array unit) */
   3935      1.1  mrg 	      m = dtp->u.p.current_unit->recl
   3936      1.1  mrg 			- dtp->u.p.current_unit->bytes_left;
   3937      1.1  mrg 	      if (max_pos > m)
   3938      1.1  mrg 		{
   3939      1.1  mrg 		  length = (max_pos - m);
   3940      1.1  mrg 		  if (sseek (dtp->u.p.current_unit->s,
   3941      1.1  mrg 			     length, SEEK_CUR) < 0)
   3942      1.1  mrg 		    {
   3943      1.1  mrg 		      generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3944      1.1  mrg 		      return;
   3945      1.1  mrg 		    }
   3946      1.1  mrg 		  length = ((size_t) dtp->u.p.current_unit->recl - max_pos);
   3947      1.1  mrg 		}
   3948      1.1  mrg 
   3949      1.1  mrg 	      p = write_block (dtp, length);
   3950      1.1  mrg 	      if (p == NULL)
   3951      1.1  mrg 		return;
   3952      1.1  mrg 
   3953      1.1  mrg 	      if (unlikely (is_char4_unit (dtp)))
   3954      1.1  mrg 	        {
   3955      1.1  mrg 		  gfc_char4_t *p4 = (gfc_char4_t *) p;
   3956      1.1  mrg 		  memset4 (p4, ' ', length);
   3957      1.1  mrg 		}
   3958      1.1  mrg 	      else
   3959      1.1  mrg 		memset (p, ' ', length);
   3960      1.1  mrg 
   3961      1.1  mrg 	      /* Now that the current record has been padded out,
   3962      1.1  mrg 		 determine where the next record in the array is.
   3963      1.1  mrg 		 Note that this can return a negative value, so it
   3964      1.1  mrg 		 needs to be assigned to a signed value.  */
   3965      1.1  mrg 	      gfc_offset record = next_array_record
   3966      1.1  mrg 		(dtp, dtp->u.p.current_unit->ls, &finished);
   3967      1.1  mrg 	      if (finished)
   3968      1.1  mrg 		dtp->u.p.current_unit->endfile = AT_ENDFILE;
   3969      1.1  mrg 
   3970      1.1  mrg 	      /* Now seek to this record */
   3971      1.1  mrg 	      record = record * dtp->u.p.current_unit->recl;
   3972      1.1  mrg 
   3973      1.1  mrg 	      if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
   3974      1.1  mrg 		{
   3975      1.1  mrg 		  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3976      1.1  mrg 		  return;
   3977      1.1  mrg 		}
   3978      1.1  mrg 
   3979      1.1  mrg 	      dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
   3980      1.1  mrg 	    }
   3981      1.1  mrg 	  else
   3982      1.1  mrg 	    {
   3983      1.1  mrg 	      length = 1;
   3984      1.1  mrg 
   3985      1.1  mrg 	      /* If this is the last call to next_record move to the farthest
   3986      1.1  mrg 		 position reached and set length to pad out the remainder
   3987      1.1  mrg 		 of the record. (for character scaler unit) */
   3988      1.1  mrg 	      if (done)
   3989      1.1  mrg 		{
   3990      1.1  mrg 		  m = dtp->u.p.current_unit->recl
   3991      1.1  mrg 			- dtp->u.p.current_unit->bytes_left;
   3992      1.1  mrg 		  if (max_pos > m)
   3993      1.1  mrg 		    {
   3994      1.1  mrg 		      length = max_pos - m;
   3995      1.1  mrg 		      if (sseek (dtp->u.p.current_unit->s,
   3996      1.1  mrg 				 length, SEEK_CUR) < 0)
   3997      1.1  mrg 		        {
   3998      1.1  mrg 			  generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
   3999      1.1  mrg 			  return;
   4000      1.1  mrg 			}
   4001      1.1  mrg 		      length = (size_t) dtp->u.p.current_unit->recl
   4002      1.1  mrg 			- max_pos;
   4003      1.1  mrg 		    }
   4004      1.1  mrg 		  else
   4005      1.1  mrg 		    length = dtp->u.p.current_unit->bytes_left;
   4006      1.1  mrg 		}
   4007      1.1  mrg 	      if (length > 0)
   4008      1.1  mrg 		{
   4009      1.1  mrg 		  p = write_block (dtp, length);
   4010      1.1  mrg 		  if (p == NULL)
   4011      1.1  mrg 		    return;
   4012      1.1  mrg 
   4013      1.1  mrg 		  if (unlikely (is_char4_unit (dtp)))
   4014      1.1  mrg 		    {
   4015      1.1  mrg 		      gfc_char4_t *p4 = (gfc_char4_t *) p;
   4016      1.1  mrg 		      memset4 (p4, (gfc_char4_t) ' ', length);
   4017      1.1  mrg 		    }
   4018      1.1  mrg 		  else
   4019      1.1  mrg 		    memset (p, ' ', length);
   4020      1.1  mrg 		}
   4021      1.1  mrg 	    }
   4022      1.1  mrg 	}
   4023      1.1  mrg       /* Handle legacy CARRIAGECONTROL line endings.  */
   4024      1.1  mrg       else if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
   4025      1.1  mrg 	next_record_cc (dtp);
   4026      1.1  mrg       else
   4027      1.1  mrg 	{
   4028      1.1  mrg 	  /* Skip newlines for CC=CC_NONE.  */
   4029      1.1  mrg 	  const int len = (dtp->u.p.current_unit->flags.cc == CC_NONE)
   4030      1.1  mrg 	    ? 0
   4031      1.1  mrg #ifdef HAVE_CRLF
   4032      1.1  mrg 	    : 2;
   4033      1.1  mrg #else
   4034      1.1  mrg 	    : 1;
   4035      1.1  mrg #endif
   4036      1.1  mrg 	  fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   4037      1.1  mrg 	  if (dtp->u.p.current_unit->flags.cc != CC_NONE)
   4038      1.1  mrg 	    {
   4039      1.1  mrg 	      char *p = fbuf_alloc (dtp->u.p.current_unit, len);
   4040      1.1  mrg 	      if (!p)
   4041      1.1  mrg 		goto io_error;
   4042      1.1  mrg #ifdef HAVE_CRLF
   4043      1.1  mrg 	      *(p++) = '\r';
   4044      1.1  mrg #endif
   4045      1.1  mrg 	      *p = '\n';
   4046      1.1  mrg 	    }
   4047      1.1  mrg 	  if (is_stream_io (dtp))
   4048      1.1  mrg 	    {
   4049      1.1  mrg 	      dtp->u.p.current_unit->strm_pos += len;
   4050      1.1  mrg 	      if (dtp->u.p.current_unit->strm_pos
   4051      1.1  mrg 		  < ssize (dtp->u.p.current_unit->s))
   4052      1.1  mrg 		unit_truncate (dtp->u.p.current_unit,
   4053      1.1  mrg                                dtp->u.p.current_unit->strm_pos - 1,
   4054      1.1  mrg                                &dtp->common);
   4055      1.1  mrg 	    }
   4056      1.1  mrg 	}
   4057      1.1  mrg 
   4058      1.1  mrg       break;
   4059  1.1.1.2  mrg     case FORMATTED_UNSPECIFIED:
   4060  1.1.1.2  mrg       gcc_unreachable ();
   4061      1.1  mrg 
   4062      1.1  mrg     io_error:
   4063      1.1  mrg       generate_error (&dtp->common, LIBERROR_OS, NULL);
   4064      1.1  mrg       break;
   4065      1.1  mrg     }
   4066      1.1  mrg }
   4067      1.1  mrg 
   4068      1.1  mrg /* Position to the next record, which means moving to the end of the
   4069      1.1  mrg    current record.  This can happen under several different
   4070      1.1  mrg    conditions.  If the done flag is not set, we get ready to process
   4071      1.1  mrg    the next record.  */
   4072      1.1  mrg 
   4073      1.1  mrg void
   4074      1.1  mrg next_record (st_parameter_dt *dtp, int done)
   4075      1.1  mrg {
   4076      1.1  mrg   gfc_offset fp; /* File position.  */
   4077      1.1  mrg 
   4078      1.1  mrg   dtp->u.p.current_unit->read_bad = 0;
   4079      1.1  mrg 
   4080      1.1  mrg   if (dtp->u.p.mode == READING)
   4081      1.1  mrg     next_record_r (dtp, done);
   4082      1.1  mrg   else
   4083      1.1  mrg     next_record_w (dtp, done);
   4084      1.1  mrg 
   4085      1.1  mrg   fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
   4086      1.1  mrg 
   4087      1.1  mrg   if (!is_stream_io (dtp))
   4088      1.1  mrg     {
   4089      1.1  mrg       /* Since we have changed the position, set it to unspecified so
   4090      1.1  mrg 	 that INQUIRE(POSITION=) knows it needs to look into it.  */
   4091      1.1  mrg       if (done)
   4092      1.1  mrg 	dtp->u.p.current_unit->flags.position = POSITION_UNSPECIFIED;
   4093      1.1  mrg 
   4094      1.1  mrg       dtp->u.p.current_unit->current_record = 0;
   4095      1.1  mrg       if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
   4096      1.1  mrg 	{
   4097      1.1  mrg 	  fp = stell (dtp->u.p.current_unit->s);
   4098      1.1  mrg 	  /* Calculate next record, rounding up partial records.  */
   4099      1.1  mrg 	  dtp->u.p.current_unit->last_record =
   4100      1.1  mrg 	    (fp + dtp->u.p.current_unit->recl) /
   4101      1.1  mrg 	      dtp->u.p.current_unit->recl - 1;
   4102      1.1  mrg 	}
   4103      1.1  mrg       else
   4104      1.1  mrg 	dtp->u.p.current_unit->last_record++;
   4105      1.1  mrg     }
   4106      1.1  mrg 
   4107      1.1  mrg   if (!done)
   4108      1.1  mrg     pre_position (dtp);
   4109      1.1  mrg 
   4110      1.1  mrg   smarkeor (dtp->u.p.current_unit->s);
   4111      1.1  mrg }
   4112      1.1  mrg 
   4113      1.1  mrg 
   4114      1.1  mrg /* Finalize the current data transfer.  For a nonadvancing transfer,
   4115      1.1  mrg    this means advancing to the next record.  For internal units close the
   4116      1.1  mrg    stream associated with the unit.  */
   4117      1.1  mrg 
   4118      1.1  mrg static void
   4119      1.1  mrg finalize_transfer (st_parameter_dt *dtp)
   4120      1.1  mrg {
   4121      1.1  mrg   GFC_INTEGER_4 cf = dtp->common.flags;
   4122      1.1  mrg 
   4123      1.1  mrg   if ((dtp->u.p.ionml != NULL)
   4124      1.1  mrg       && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
   4125      1.1  mrg     {
   4126      1.1  mrg        dtp->u.p.namelist_mode = 1;
   4127      1.1  mrg        if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
   4128      1.1  mrg 	 namelist_read (dtp);
   4129      1.1  mrg        else
   4130      1.1  mrg 	 namelist_write (dtp);
   4131      1.1  mrg     }
   4132      1.1  mrg 
   4133      1.1  mrg   if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
   4134      1.1  mrg     *dtp->size = dtp->u.p.current_unit->size_used;
   4135      1.1  mrg 
   4136      1.1  mrg   if (dtp->u.p.eor_condition)
   4137      1.1  mrg     {
   4138      1.1  mrg       generate_error (&dtp->common, LIBERROR_EOR, NULL);
   4139      1.1  mrg       goto done;
   4140      1.1  mrg     }
   4141      1.1  mrg 
   4142      1.1  mrg   if (dtp->u.p.current_unit && (dtp->u.p.current_unit->child_dtio  > 0))
   4143      1.1  mrg     {
   4144      1.1  mrg       if (cf & IOPARM_DT_HAS_FORMAT)
   4145      1.1  mrg         {
   4146      1.1  mrg 	  free (dtp->u.p.fmt);
   4147      1.1  mrg 	  free (dtp->format);
   4148      1.1  mrg 	}
   4149      1.1  mrg       return;
   4150      1.1  mrg     }
   4151      1.1  mrg 
   4152      1.1  mrg   if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
   4153      1.1  mrg     {
   4154      1.1  mrg       if (dtp->u.p.current_unit && current_mode (dtp) == UNFORMATTED_SEQUENTIAL)
   4155      1.1  mrg 	dtp->u.p.current_unit->current_record = 0;
   4156      1.1  mrg       goto done;
   4157      1.1  mrg     }
   4158      1.1  mrg 
   4159      1.1  mrg   dtp->u.p.transfer = NULL;
   4160      1.1  mrg   if (dtp->u.p.current_unit == NULL)
   4161      1.1  mrg     goto done;
   4162      1.1  mrg 
   4163      1.1  mrg   if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
   4164      1.1  mrg     {
   4165      1.1  mrg       finish_list_read (dtp);
   4166      1.1  mrg       goto done;
   4167      1.1  mrg     }
   4168      1.1  mrg 
   4169      1.1  mrg   if (dtp->u.p.mode == WRITING)
   4170      1.1  mrg     dtp->u.p.current_unit->previous_nonadvancing_write
   4171      1.1  mrg       = dtp->u.p.advance_status == ADVANCE_NO;
   4172      1.1  mrg 
   4173      1.1  mrg   if (is_stream_io (dtp))
   4174      1.1  mrg     {
   4175      1.1  mrg       if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
   4176      1.1  mrg 	  && dtp->u.p.advance_status != ADVANCE_NO)
   4177      1.1  mrg 	next_record (dtp, 1);
   4178      1.1  mrg 
   4179      1.1  mrg       goto done;
   4180      1.1  mrg     }
   4181      1.1  mrg 
   4182      1.1  mrg   dtp->u.p.current_unit->current_record = 0;
   4183      1.1  mrg 
   4184      1.1  mrg   if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
   4185      1.1  mrg     {
   4186      1.1  mrg       fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
   4187      1.1  mrg       dtp->u.p.seen_dollar = 0;
   4188      1.1  mrg       goto done;
   4189      1.1  mrg     }
   4190      1.1  mrg 
   4191      1.1  mrg   /* For non-advancing I/O, save the current maximum position for use in the
   4192      1.1  mrg      next I/O operation if needed.  */
   4193      1.1  mrg   if (dtp->u.p.advance_status == ADVANCE_NO)
   4194      1.1  mrg     {
   4195      1.1  mrg       if (dtp->u.p.skips > 0)
   4196      1.1  mrg 	{
   4197      1.1  mrg 	  int tmp;
   4198      1.1  mrg 	  write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
   4199      1.1  mrg 	  tmp = (int)(dtp->u.p.current_unit->recl
   4200      1.1  mrg 		      - dtp->u.p.current_unit->bytes_left);
   4201      1.1  mrg 	  dtp->u.p.max_pos =
   4202      1.1  mrg 	    dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
   4203      1.1  mrg 	  dtp->u.p.skips = 0;
   4204      1.1  mrg 	}
   4205      1.1  mrg       int bytes_written = (int) (dtp->u.p.current_unit->recl
   4206      1.1  mrg 	- dtp->u.p.current_unit->bytes_left);
   4207      1.1  mrg       dtp->u.p.current_unit->saved_pos =
   4208      1.1  mrg 	dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
   4209      1.1  mrg       fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
   4210      1.1  mrg       goto done;
   4211      1.1  mrg     }
   4212      1.1  mrg   else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
   4213      1.1  mrg            && dtp->u.p.mode == WRITING && !is_internal_unit (dtp))
   4214      1.1  mrg       fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
   4215      1.1  mrg 
   4216      1.1  mrg   dtp->u.p.current_unit->saved_pos = 0;
   4217      1.1  mrg   dtp->u.p.current_unit->last_char = EOF - 1;
   4218      1.1  mrg   next_record (dtp, 1);
   4219      1.1  mrg 
   4220      1.1  mrg  done:
   4221      1.1  mrg 
   4222      1.1  mrg   if (dtp->u.p.unit_is_internal)
   4223      1.1  mrg     {
   4224      1.1  mrg       /* The unit structure may be reused later so clear the
   4225      1.1  mrg 	 internal unit kind.  */
   4226      1.1  mrg       dtp->u.p.current_unit->internal_unit_kind = 0;
   4227      1.1  mrg 
   4228      1.1  mrg       fbuf_destroy (dtp->u.p.current_unit);
   4229      1.1  mrg       if (dtp->u.p.current_unit
   4230      1.1  mrg 	  && (dtp->u.p.current_unit->child_dtio  == 0)
   4231      1.1  mrg 	  && dtp->u.p.current_unit->s)
   4232      1.1  mrg 	{
   4233      1.1  mrg 	  sclose (dtp->u.p.current_unit->s);
   4234      1.1  mrg 	  dtp->u.p.current_unit->s = NULL;
   4235      1.1  mrg 	}
   4236      1.1  mrg     }
   4237      1.1  mrg 
   4238      1.1  mrg #ifdef HAVE_USELOCALE
   4239      1.1  mrg   if (dtp->u.p.old_locale != (locale_t) 0)
   4240      1.1  mrg     {
   4241      1.1  mrg       uselocale (dtp->u.p.old_locale);
   4242      1.1  mrg       dtp->u.p.old_locale = (locale_t) 0;
   4243      1.1  mrg     }
   4244      1.1  mrg #else
   4245      1.1  mrg   __gthread_mutex_lock (&old_locale_lock);
   4246      1.1  mrg   if (!--old_locale_ctr)
   4247      1.1  mrg     {
   4248      1.1  mrg       setlocale (LC_NUMERIC, old_locale);
   4249      1.1  mrg       old_locale = NULL;
   4250      1.1  mrg     }
   4251      1.1  mrg   __gthread_mutex_unlock (&old_locale_lock);
   4252      1.1  mrg #endif
   4253      1.1  mrg }
   4254      1.1  mrg 
   4255      1.1  mrg /* Transfer function for IOLENGTH. It doesn't actually do any
   4256      1.1  mrg    data transfer, it just updates the length counter.  */
   4257      1.1  mrg 
   4258      1.1  mrg static void
   4259      1.1  mrg iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
   4260      1.1  mrg 		   void *dest __attribute__ ((unused)),
   4261      1.1  mrg 		   int kind __attribute__((unused)),
   4262      1.1  mrg 		   size_t size, size_t nelems)
   4263      1.1  mrg {
   4264      1.1  mrg   if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
   4265      1.1  mrg     *dtp->iolength += (GFC_IO_INT) (size * nelems);
   4266      1.1  mrg }
   4267      1.1  mrg 
   4268      1.1  mrg 
   4269      1.1  mrg /* Initialize the IOLENGTH data transfer. This function is in essence
   4270      1.1  mrg    a very much simplified version of data_transfer_init(), because it
   4271      1.1  mrg    doesn't have to deal with units at all.  */
   4272      1.1  mrg 
   4273      1.1  mrg static void
   4274      1.1  mrg iolength_transfer_init (st_parameter_dt *dtp)
   4275      1.1  mrg {
   4276      1.1  mrg   if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
   4277      1.1  mrg     *dtp->iolength = 0;
   4278      1.1  mrg 
   4279      1.1  mrg   memset (&dtp->u.p, 0, sizeof (dtp->u.p));
   4280      1.1  mrg 
   4281      1.1  mrg   /* Set up the subroutine that will handle the transfers.  */
   4282      1.1  mrg 
   4283      1.1  mrg   dtp->u.p.transfer = iolength_transfer;
   4284      1.1  mrg }
   4285      1.1  mrg 
   4286      1.1  mrg 
   4287      1.1  mrg /* Library entry point for the IOLENGTH form of the INQUIRE
   4288      1.1  mrg    statement. The IOLENGTH form requires no I/O to be performed, but
   4289      1.1  mrg    it must still be a runtime library call so that we can determine
   4290      1.1  mrg    the iolength for dynamic arrays and such.  */
   4291      1.1  mrg 
   4292      1.1  mrg extern void st_iolength (st_parameter_dt *);
   4293      1.1  mrg export_proto(st_iolength);
   4294      1.1  mrg 
   4295      1.1  mrg void
   4296      1.1  mrg st_iolength (st_parameter_dt *dtp)
   4297      1.1  mrg {
   4298      1.1  mrg   library_start (&dtp->common);
   4299      1.1  mrg   iolength_transfer_init (dtp);
   4300      1.1  mrg }
   4301      1.1  mrg 
   4302      1.1  mrg extern void st_iolength_done (st_parameter_dt *);
   4303      1.1  mrg export_proto(st_iolength_done);
   4304      1.1  mrg 
   4305      1.1  mrg void
   4306      1.1  mrg st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
   4307      1.1  mrg {
   4308      1.1  mrg   free_ionml (dtp);
   4309      1.1  mrg   library_end ();
   4310      1.1  mrg }
   4311      1.1  mrg 
   4312      1.1  mrg 
   4313      1.1  mrg /* The READ statement.  */
   4314      1.1  mrg 
   4315      1.1  mrg extern void st_read (st_parameter_dt *);
   4316      1.1  mrg export_proto(st_read);
   4317      1.1  mrg 
   4318      1.1  mrg void
   4319      1.1  mrg st_read (st_parameter_dt *dtp)
   4320      1.1  mrg {
   4321      1.1  mrg   library_start (&dtp->common);
   4322      1.1  mrg 
   4323      1.1  mrg   data_transfer_init (dtp, 1);
   4324      1.1  mrg }
   4325      1.1  mrg 
   4326      1.1  mrg extern void st_read_done (st_parameter_dt *);
   4327      1.1  mrg export_proto(st_read_done);
   4328      1.1  mrg 
   4329      1.1  mrg void
   4330      1.1  mrg st_read_done_worker (st_parameter_dt *dtp)
   4331      1.1  mrg {
   4332      1.1  mrg   finalize_transfer (dtp);
   4333      1.1  mrg 
   4334      1.1  mrg   free_ionml (dtp);
   4335      1.1  mrg 
   4336      1.1  mrg   /* If this is a parent READ statement we do not need to retain the
   4337      1.1  mrg      internal unit structure for child use.  */
   4338      1.1  mrg   if (dtp->u.p.current_unit != NULL
   4339      1.1  mrg       && dtp->u.p.current_unit->child_dtio == 0)
   4340      1.1  mrg     {
   4341      1.1  mrg       if (dtp->u.p.unit_is_internal)
   4342      1.1  mrg 	{
   4343      1.1  mrg 	  if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
   4344      1.1  mrg 	    {
   4345      1.1  mrg 	      free (dtp->u.p.current_unit->filename);
   4346      1.1  mrg 	      dtp->u.p.current_unit->filename = NULL;
   4347      1.1  mrg 	      if (dtp->u.p.current_unit->ls)
   4348      1.1  mrg 		free (dtp->u.p.current_unit->ls);
   4349      1.1  mrg 	      dtp->u.p.current_unit->ls = NULL;
   4350      1.1  mrg 	    }
   4351      1.1  mrg 	  newunit_free (dtp->common.unit);
   4352      1.1  mrg 	}
   4353      1.1  mrg       if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
   4354      1.1  mrg 	{
   4355      1.1  mrg 	  free_format_data (dtp->u.p.fmt);
   4356      1.1  mrg 	  free_format (dtp);
   4357      1.1  mrg 	}
   4358      1.1  mrg     }
   4359      1.1  mrg }
   4360      1.1  mrg 
   4361      1.1  mrg void
   4362      1.1  mrg st_read_done (st_parameter_dt *dtp)
   4363      1.1  mrg {
   4364      1.1  mrg   if (dtp->u.p.current_unit)
   4365      1.1  mrg     {
   4366      1.1  mrg       if (dtp->u.p.current_unit->au)
   4367      1.1  mrg 	{
   4368      1.1  mrg 	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
   4369      1.1  mrg 	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);
   4370      1.1  mrg 	  else
   4371      1.1  mrg 	    {
   4372      1.1  mrg 	      if (dtp->u.p.async)
   4373      1.1  mrg 		enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
   4374      1.1  mrg 	    }
   4375      1.1  mrg 	}
   4376      1.1  mrg       else
   4377      1.1  mrg 	st_read_done_worker (dtp);
   4378      1.1  mrg 
   4379      1.1  mrg       unlock_unit (dtp->u.p.current_unit);
   4380      1.1  mrg     }
   4381      1.1  mrg 
   4382      1.1  mrg   library_end ();
   4383      1.1  mrg }
   4384      1.1  mrg 
   4385      1.1  mrg extern void st_write (st_parameter_dt *);
   4386      1.1  mrg export_proto (st_write);
   4387      1.1  mrg 
   4388      1.1  mrg void
   4389      1.1  mrg st_write (st_parameter_dt *dtp)
   4390      1.1  mrg {
   4391      1.1  mrg   library_start (&dtp->common);
   4392      1.1  mrg   data_transfer_init (dtp, 0);
   4393      1.1  mrg }
   4394      1.1  mrg 
   4395      1.1  mrg 
   4396      1.1  mrg void
   4397      1.1  mrg st_write_done_worker (st_parameter_dt *dtp)
   4398      1.1  mrg {
   4399      1.1  mrg   finalize_transfer (dtp);
   4400      1.1  mrg 
   4401      1.1  mrg   if (dtp->u.p.current_unit != NULL
   4402      1.1  mrg       && dtp->u.p.current_unit->child_dtio == 0)
   4403      1.1  mrg     {
   4404      1.1  mrg       /* Deal with endfile conditions associated with sequential files.  */
   4405      1.1  mrg       if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
   4406      1.1  mrg 	switch (dtp->u.p.current_unit->endfile)
   4407      1.1  mrg 	  {
   4408      1.1  mrg 	  case AT_ENDFILE:		/* Remain at the endfile record.  */
   4409      1.1  mrg 	    break;
   4410      1.1  mrg 
   4411      1.1  mrg 	  case AFTER_ENDFILE:
   4412      1.1  mrg 	    dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now.  */
   4413      1.1  mrg 	    break;
   4414      1.1  mrg 
   4415      1.1  mrg 	  case NO_ENDFILE:
   4416      1.1  mrg 	    /* Get rid of whatever is after this record.  */
   4417      1.1  mrg 	    if (!is_internal_unit (dtp))
   4418      1.1  mrg 	      unit_truncate (dtp->u.p.current_unit,
   4419      1.1  mrg 			     stell (dtp->u.p.current_unit->s),
   4420      1.1  mrg 			     &dtp->common);
   4421      1.1  mrg 	    dtp->u.p.current_unit->endfile = AT_ENDFILE;
   4422      1.1  mrg 	    break;
   4423      1.1  mrg 	  }
   4424      1.1  mrg 
   4425      1.1  mrg       free_ionml (dtp);
   4426      1.1  mrg 
   4427      1.1  mrg       /* If this is a parent WRITE statement we do not need to retain the
   4428      1.1  mrg 	 internal unit structure for child use.  */
   4429      1.1  mrg       if (dtp->u.p.unit_is_internal)
   4430      1.1  mrg 	{
   4431      1.1  mrg 	  if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
   4432      1.1  mrg 	    {
   4433      1.1  mrg 	      free (dtp->u.p.current_unit->filename);
   4434      1.1  mrg 	      dtp->u.p.current_unit->filename = NULL;
   4435      1.1  mrg 	      if (dtp->u.p.current_unit->ls)
   4436      1.1  mrg 		free (dtp->u.p.current_unit->ls);
   4437      1.1  mrg 	      dtp->u.p.current_unit->ls = NULL;
   4438      1.1  mrg 	    }
   4439      1.1  mrg 	  newunit_free (dtp->common.unit);
   4440      1.1  mrg 	}
   4441      1.1  mrg       if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
   4442      1.1  mrg 	{
   4443      1.1  mrg 	  free_format_data (dtp->u.p.fmt);
   4444      1.1  mrg 	  free_format (dtp);
   4445      1.1  mrg 	}
   4446      1.1  mrg     }
   4447      1.1  mrg }
   4448      1.1  mrg 
   4449      1.1  mrg extern void st_write_done (st_parameter_dt *);
   4450      1.1  mrg export_proto(st_write_done);
   4451      1.1  mrg 
   4452      1.1  mrg void
   4453      1.1  mrg st_write_done (st_parameter_dt *dtp)
   4454      1.1  mrg {
   4455      1.1  mrg   if (dtp->u.p.current_unit)
   4456      1.1  mrg     {
   4457      1.1  mrg       if (dtp->u.p.current_unit->au && dtp->u.p.async)
   4458      1.1  mrg 	{
   4459      1.1  mrg 	  if (dtp->common.flags & IOPARM_DT_HAS_ID)
   4460      1.1  mrg 	    *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
   4461      1.1  mrg 					AIO_WRITE_DONE);
   4462      1.1  mrg 	  else
   4463      1.1  mrg 	    {
   4464      1.1  mrg 	      /* We perform synchronous I/O on an asynchronous unit, so no need
   4465      1.1  mrg 		 to enqueue AIO_READ_DONE.  */
   4466      1.1  mrg 	      if (dtp->u.p.async)
   4467      1.1  mrg 		enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
   4468      1.1  mrg 	    }
   4469      1.1  mrg 	}
   4470      1.1  mrg       else
   4471      1.1  mrg 	st_write_done_worker (dtp);
   4472      1.1  mrg 
   4473      1.1  mrg       unlock_unit (dtp->u.p.current_unit);
   4474      1.1  mrg     }
   4475      1.1  mrg 
   4476      1.1  mrg   library_end ();
   4477      1.1  mrg }
   4478      1.1  mrg 
   4479      1.1  mrg /* Wait operation.  We need to keep around the do-nothing version
   4480      1.1  mrg  of st_wait for compatibility with previous versions, which had marked
   4481      1.1  mrg  the argument as unused (and thus liable to be removed).
   4482      1.1  mrg 
   4483      1.1  mrg  TODO: remove at next bump in version number.  */
   4484      1.1  mrg 
   4485      1.1  mrg void
   4486      1.1  mrg st_wait (st_parameter_wait *wtp __attribute__((unused)))
   4487      1.1  mrg {
   4488      1.1  mrg   return;
   4489      1.1  mrg }
   4490      1.1  mrg 
   4491      1.1  mrg void
   4492      1.1  mrg st_wait_async (st_parameter_wait *wtp)
   4493      1.1  mrg {
   4494      1.1  mrg   gfc_unit *u = find_unit (wtp->common.unit);
   4495  1.1.1.2  mrg   if (ASYNC_IO && u && u->au)
   4496      1.1  mrg     {
   4497      1.1  mrg       if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
   4498      1.1  mrg 	async_wait_id (&(wtp->common), u->au, *wtp->id);
   4499      1.1  mrg       else
   4500      1.1  mrg 	async_wait (&(wtp->common), u->au);
   4501      1.1  mrg     }
   4502      1.1  mrg 
   4503      1.1  mrg   unlock_unit (u);
   4504      1.1  mrg }
   4505      1.1  mrg 
   4506      1.1  mrg 
   4507      1.1  mrg /* Receives the scalar information for namelist objects and stores it
   4508      1.1  mrg    in a linked list of namelist_info types.  */
   4509      1.1  mrg 
   4510      1.1  mrg static void
   4511      1.1  mrg set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
   4512      1.1  mrg 	     GFC_INTEGER_4 len, gfc_charlen_type string_length,
   4513      1.1  mrg 	     dtype_type dtype, void *dtio_sub, void *vtable)
   4514      1.1  mrg {
   4515      1.1  mrg   namelist_info *t1 = NULL;
   4516      1.1  mrg   namelist_info *nml;
   4517      1.1  mrg   size_t var_name_len = strlen (var_name);
   4518      1.1  mrg 
   4519      1.1  mrg   nml = (namelist_info*) xmalloc (sizeof (namelist_info));
   4520      1.1  mrg 
   4521      1.1  mrg   nml->mem_pos = var_addr;
   4522      1.1  mrg   nml->dtio_sub = dtio_sub;
   4523      1.1  mrg   nml->vtable = vtable;
   4524      1.1  mrg 
   4525      1.1  mrg   nml->var_name = (char*) xmalloc (var_name_len + 1);
   4526      1.1  mrg   memcpy (nml->var_name, var_name, var_name_len);
   4527      1.1  mrg   nml->var_name[var_name_len] = '\0';
   4528      1.1  mrg 
   4529      1.1  mrg   nml->len = (int) len;
   4530      1.1  mrg   nml->string_length = (index_type) string_length;
   4531      1.1  mrg 
   4532      1.1  mrg   nml->var_rank = (int) (dtype.rank);
   4533      1.1  mrg   nml->size = (index_type) (dtype.elem_len);
   4534      1.1  mrg   nml->type = (bt) (dtype.type);
   4535      1.1  mrg 
   4536      1.1  mrg   if (nml->var_rank > 0)
   4537      1.1  mrg     {
   4538      1.1  mrg       nml->dim = (descriptor_dimension*)
   4539      1.1  mrg 	xmallocarray (nml->var_rank, sizeof (descriptor_dimension));
   4540      1.1  mrg       nml->ls = (array_loop_spec*)
   4541      1.1  mrg 	xmallocarray (nml->var_rank, sizeof (array_loop_spec));
   4542      1.1  mrg     }
   4543      1.1  mrg   else
   4544      1.1  mrg     {
   4545      1.1  mrg       nml->dim = NULL;
   4546      1.1  mrg       nml->ls = NULL;
   4547      1.1  mrg     }
   4548      1.1  mrg 
   4549      1.1  mrg   nml->next = NULL;
   4550      1.1  mrg 
   4551      1.1  mrg   if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
   4552      1.1  mrg     {
   4553      1.1  mrg       dtp->common.flags |= IOPARM_DT_IONML_SET;
   4554      1.1  mrg       dtp->u.p.ionml = nml;
   4555      1.1  mrg     }
   4556      1.1  mrg   else
   4557      1.1  mrg     {
   4558      1.1  mrg       for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
   4559      1.1  mrg       t1->next = nml;
   4560      1.1  mrg     }
   4561      1.1  mrg }
   4562      1.1  mrg 
   4563      1.1  mrg extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
   4564      1.1  mrg 			    GFC_INTEGER_4, gfc_charlen_type, dtype_type);
   4565      1.1  mrg export_proto(st_set_nml_var);
   4566      1.1  mrg 
   4567      1.1  mrg void
   4568      1.1  mrg st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
   4569      1.1  mrg 		GFC_INTEGER_4 len, gfc_charlen_type string_length,
   4570      1.1  mrg 		dtype_type dtype)
   4571      1.1  mrg {
   4572      1.1  mrg   set_nml_var (dtp, var_addr, var_name, len, string_length,
   4573      1.1  mrg 	       dtype, NULL, NULL);
   4574      1.1  mrg }
   4575      1.1  mrg 
   4576      1.1  mrg 
   4577      1.1  mrg /* Essentially the same as previous but carrying the dtio procedure
   4578      1.1  mrg    and the vtable as additional arguments.  */
   4579      1.1  mrg extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
   4580      1.1  mrg 				 GFC_INTEGER_4, gfc_charlen_type, dtype_type,
   4581      1.1  mrg 				 void *, void *);
   4582      1.1  mrg export_proto(st_set_nml_dtio_var);
   4583      1.1  mrg 
   4584      1.1  mrg 
   4585      1.1  mrg void
   4586      1.1  mrg st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
   4587      1.1  mrg 		     GFC_INTEGER_4 len, gfc_charlen_type string_length,
   4588      1.1  mrg 		     dtype_type dtype, void *dtio_sub, void *vtable)
   4589      1.1  mrg {
   4590      1.1  mrg   set_nml_var (dtp, var_addr, var_name, len, string_length,
   4591      1.1  mrg 	       dtype, dtio_sub, vtable);
   4592      1.1  mrg }
   4593      1.1  mrg 
   4594      1.1  mrg /* Store the dimensional information for the namelist object.  */
   4595      1.1  mrg extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
   4596      1.1  mrg 				index_type, index_type,
   4597      1.1  mrg 				index_type);
   4598      1.1  mrg export_proto(st_set_nml_var_dim);
   4599      1.1  mrg 
   4600      1.1  mrg void
   4601      1.1  mrg st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
   4602      1.1  mrg 		    index_type stride, index_type lbound,
   4603      1.1  mrg 		    index_type ubound)
   4604      1.1  mrg {
   4605      1.1  mrg   namelist_info *nml;
   4606      1.1  mrg   int n;
   4607      1.1  mrg 
   4608      1.1  mrg   n = (int)n_dim;
   4609      1.1  mrg 
   4610      1.1  mrg   for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);
   4611      1.1  mrg 
   4612      1.1  mrg   GFC_DIMENSION_SET(nml->dim[n],lbound,ubound,stride);
   4613      1.1  mrg }
   4614      1.1  mrg 
   4615      1.1  mrg 
   4616      1.1  mrg /* Once upon a time, a poor innocent Fortran program was reading a
   4617      1.1  mrg    file, when suddenly it hit the end-of-file (EOF).  Unfortunately
   4618      1.1  mrg    the OS doesn't tell whether we're at the EOF or whether we already
   4619      1.1  mrg    went past it.  Luckily our hero, libgfortran, keeps track of this.
   4620      1.1  mrg    Call this function when you detect an EOF condition.  See Section
   4621      1.1  mrg    9.10.2 in F2003.  */
   4622      1.1  mrg 
   4623      1.1  mrg void
   4624      1.1  mrg hit_eof (st_parameter_dt *dtp)
   4625      1.1  mrg {
   4626      1.1  mrg   dtp->u.p.current_unit->flags.position = POSITION_APPEND;
   4627      1.1  mrg 
   4628      1.1  mrg   if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
   4629      1.1  mrg     switch (dtp->u.p.current_unit->endfile)
   4630      1.1  mrg       {
   4631      1.1  mrg       case NO_ENDFILE:
   4632      1.1  mrg       case AT_ENDFILE:
   4633      1.1  mrg         generate_error (&dtp->common, LIBERROR_END, NULL);
   4634      1.1  mrg 	if (!is_internal_unit (dtp) && !dtp->u.p.namelist_mode)
   4635      1.1  mrg 	  {
   4636      1.1  mrg 	    dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
   4637      1.1  mrg 	    dtp->u.p.current_unit->current_record = 0;
   4638      1.1  mrg 	  }
   4639      1.1  mrg         else
   4640      1.1  mrg           dtp->u.p.current_unit->endfile = AT_ENDFILE;
   4641      1.1  mrg 	break;
   4642      1.1  mrg 
   4643      1.1  mrg       case AFTER_ENDFILE:
   4644      1.1  mrg 	generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
   4645      1.1  mrg 	dtp->u.p.current_unit->current_record = 0;
   4646      1.1  mrg 	break;
   4647      1.1  mrg       }
   4648      1.1  mrg   else
   4649      1.1  mrg     {
   4650      1.1  mrg       /* Non-sequential files don't have an ENDFILE record, so we
   4651      1.1  mrg          can't be at AFTER_ENDFILE.  */
   4652      1.1  mrg       dtp->u.p.current_unit->endfile = AT_ENDFILE;
   4653      1.1  mrg       generate_error (&dtp->common, LIBERROR_END, NULL);
   4654      1.1  mrg       dtp->u.p.current_unit->current_record = 0;
   4655      1.1  mrg     }
   4656      1.1  mrg }
   4657