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