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