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