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