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