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