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