re PR libfortran/35132 (Formatted stream I/O write should truncate)
[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 dtp->u.p.line_buffer = scratch;
920
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 else
1278 {
1279 if (dtp->u.p.skips < 0)
1280 flush (dtp->u.p.current_unit->s);
1281 }
1282
1283 break;
1284
1285 case FMT_S:
1286 consume_data_flag = 0 ;
1287 dtp->u.p.sign_status = SIGN_S;
1288 break;
1289
1290 case FMT_SS:
1291 consume_data_flag = 0 ;
1292 dtp->u.p.sign_status = SIGN_SS;
1293 break;
1294
1295 case FMT_SP:
1296 consume_data_flag = 0 ;
1297 dtp->u.p.sign_status = SIGN_SP;
1298 break;
1299
1300 case FMT_BN:
1301 consume_data_flag = 0 ;
1302 dtp->u.p.blank_status = BLANK_NULL;
1303 break;
1304
1305 case FMT_BZ:
1306 consume_data_flag = 0 ;
1307 dtp->u.p.blank_status = BLANK_ZERO;
1308 break;
1309
1310 case FMT_P:
1311 consume_data_flag = 0 ;
1312 dtp->u.p.scale_factor = f->u.k;
1313 break;
1314
1315 case FMT_DOLLAR:
1316 consume_data_flag = 0 ;
1317 dtp->u.p.seen_dollar = 1;
1318 break;
1319
1320 case FMT_SLASH:
1321 consume_data_flag = 0 ;
1322 dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1323 next_record (dtp, 0);
1324 break;
1325
1326 case FMT_COLON:
1327 /* A colon descriptor causes us to exit this loop (in
1328 particular preventing another / descriptor from being
1329 processed) unless there is another data item to be
1330 transferred. */
1331 consume_data_flag = 0 ;
1332 if (n == 0)
1333 return;
1334 break;
1335
1336 default:
1337 internal_error (&dtp->common, "Bad format node");
1338 }
1339
1340 /* Free a buffer that we had to allocate during a sequential
1341 formatted read of a block that was larger than the static
1342 buffer. */
1343
1344 if (dtp->u.p.line_buffer != scratch)
1345 {
1346 free_mem (dtp->u.p.line_buffer);
1347 dtp->u.p.line_buffer = scratch;
1348 }
1349
1350 /* Adjust the item count and data pointer. */
1351
1352 if ((consume_data_flag > 0) && (n > 0))
1353 {
1354 n--;
1355 p = ((char *) p) + size;
1356 }
1357
1358 if (dtp->u.p.mode == READING)
1359 dtp->u.p.skips = 0;
1360
1361 pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
1362 dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
1363
1364 }
1365
1366 return;
1367
1368 /* Come here when we need a data descriptor but don't have one. We
1369 push the current format node back onto the input, then return and
1370 let the user program call us back with the data. */
1371 need_data:
1372 unget_format (dtp, f);
1373 }
1374
1375 static void
1376 formatted_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
1377 size_t size, size_t nelems)
1378 {
1379 size_t elem;
1380 char *tmp;
1381
1382 tmp = (char *) p;
1383
1384 /* Big loop over all the elements. */
1385 for (elem = 0; elem < nelems; elem++)
1386 {
1387 dtp->u.p.item_count++;
1388 formatted_transfer_scalar (dtp, type, tmp + size*elem, kind, size);
1389 }
1390 }
1391
1392
1393
1394 /* Data transfer entry points. The type of the data entity is
1395 implicit in the subroutine call. This prevents us from having to
1396 share a common enum with the compiler. */
1397
1398 void
1399 transfer_integer (st_parameter_dt *dtp, void *p, int kind)
1400 {
1401 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1402 return;
1403 dtp->u.p.transfer (dtp, BT_INTEGER, p, kind, kind, 1);
1404 }
1405
1406
1407 void
1408 transfer_real (st_parameter_dt *dtp, void *p, int kind)
1409 {
1410 size_t size;
1411 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1412 return;
1413 size = size_from_real_kind (kind);
1414 dtp->u.p.transfer (dtp, BT_REAL, p, kind, size, 1);
1415 }
1416
1417
1418 void
1419 transfer_logical (st_parameter_dt *dtp, void *p, int kind)
1420 {
1421 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1422 return;
1423 dtp->u.p.transfer (dtp, BT_LOGICAL, p, kind, kind, 1);
1424 }
1425
1426
1427 void
1428 transfer_character (st_parameter_dt *dtp, void *p, int len)
1429 {
1430 static char *empty_string[0];
1431
1432 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1433 return;
1434
1435 /* Strings of zero length can have p == NULL, which confuses the
1436 transfer routines into thinking we need more data elements. To avoid
1437 this, we give them a nice pointer. */
1438 if (len == 0 && p == NULL)
1439 p = empty_string;
1440
1441 /* Currently we support only 1 byte chars, and the library is a bit
1442 confused of character kind vs. length, so we kludge it by setting
1443 kind = length. */
1444 dtp->u.p.transfer (dtp, BT_CHARACTER, p, len, len, 1);
1445 }
1446
1447
1448 void
1449 transfer_complex (st_parameter_dt *dtp, void *p, int kind)
1450 {
1451 size_t size;
1452 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1453 return;
1454 size = size_from_complex_kind (kind);
1455 dtp->u.p.transfer (dtp, BT_COMPLEX, p, kind, size, 1);
1456 }
1457
1458
1459 void
1460 transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
1461 gfc_charlen_type charlen)
1462 {
1463 index_type count[GFC_MAX_DIMENSIONS];
1464 index_type extent[GFC_MAX_DIMENSIONS];
1465 index_type stride[GFC_MAX_DIMENSIONS];
1466 index_type stride0, rank, size, type, n;
1467 size_t tsize;
1468 char *data;
1469 bt iotype;
1470
1471 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1472 return;
1473
1474 type = GFC_DESCRIPTOR_TYPE (desc);
1475 size = GFC_DESCRIPTOR_SIZE (desc);
1476
1477 /* FIXME: What a kludge: Array descriptors and the IO library use
1478 different enums for types. */
1479 switch (type)
1480 {
1481 case GFC_DTYPE_UNKNOWN:
1482 iotype = BT_NULL; /* Is this correct? */
1483 break;
1484 case GFC_DTYPE_INTEGER:
1485 iotype = BT_INTEGER;
1486 break;
1487 case GFC_DTYPE_LOGICAL:
1488 iotype = BT_LOGICAL;
1489 break;
1490 case GFC_DTYPE_REAL:
1491 iotype = BT_REAL;
1492 break;
1493 case GFC_DTYPE_COMPLEX:
1494 iotype = BT_COMPLEX;
1495 break;
1496 case GFC_DTYPE_CHARACTER:
1497 iotype = BT_CHARACTER;
1498 /* FIXME: Currently dtype contains the charlen, which is
1499 clobbered if charlen > 2**24. That's why we use a separate
1500 argument for the charlen. However, if we want to support
1501 non-8-bit charsets we need to fix dtype to contain
1502 sizeof(chartype) and fix the code below. */
1503 size = charlen;
1504 kind = charlen;
1505 break;
1506 case GFC_DTYPE_DERIVED:
1507 internal_error (&dtp->common,
1508 "Derived type I/O should have been handled via the frontend.");
1509 break;
1510 default:
1511 internal_error (&dtp->common, "transfer_array(): Bad type");
1512 }
1513
1514 rank = GFC_DESCRIPTOR_RANK (desc);
1515 for (n = 0; n < rank; n++)
1516 {
1517 count[n] = 0;
1518 stride[n] = desc->dim[n].stride;
1519 extent[n] = desc->dim[n].ubound + 1 - desc->dim[n].lbound;
1520
1521 /* If the extent of even one dimension is zero, then the entire
1522 array section contains zero elements, so we return after writing
1523 a zero array record. */
1524 if (extent[n] <= 0)
1525 {
1526 data = NULL;
1527 tsize = 0;
1528 dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
1529 return;
1530 }
1531 }
1532
1533 stride0 = stride[0];
1534
1535 /* If the innermost dimension has stride 1, we can do the transfer
1536 in contiguous chunks. */
1537 if (stride0 == 1)
1538 tsize = extent[0];
1539 else
1540 tsize = 1;
1541
1542 data = GFC_DESCRIPTOR_DATA (desc);
1543
1544 while (data)
1545 {
1546 dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
1547 data += stride0 * size * tsize;
1548 count[0] += tsize;
1549 n = 0;
1550 while (count[n] == extent[n])
1551 {
1552 count[n] = 0;
1553 data -= stride[n] * extent[n] * size;
1554 n++;
1555 if (n == rank)
1556 {
1557 data = NULL;
1558 break;
1559 }
1560 else
1561 {
1562 count[n]++;
1563 data += stride[n] * size;
1564 }
1565 }
1566 }
1567 }
1568
1569
1570 /* Preposition a sequential unformatted file while reading. */
1571
1572 static void
1573 us_read (st_parameter_dt *dtp, int continued)
1574 {
1575 char *p;
1576 int n;
1577 int nr;
1578 GFC_INTEGER_4 i4;
1579 GFC_INTEGER_8 i8;
1580 gfc_offset i;
1581
1582 if (dtp->u.p.current_unit->endfile == AT_ENDFILE)
1583 return;
1584
1585 if (compile_options.record_marker == 0)
1586 n = sizeof (GFC_INTEGER_4);
1587 else
1588 n = compile_options.record_marker;
1589
1590 nr = n;
1591
1592 p = salloc_r (dtp->u.p.current_unit->s, &n);
1593
1594 if (n == 0)
1595 {
1596 dtp->u.p.current_unit->endfile = AT_ENDFILE;
1597 return; /* end of file */
1598 }
1599
1600 if (p == NULL || n != nr)
1601 {
1602 generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
1603 return;
1604 }
1605
1606 /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
1607 if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
1608 {
1609 switch (nr)
1610 {
1611 case sizeof(GFC_INTEGER_4):
1612 memcpy (&i4, p, sizeof (i4));
1613 i = i4;
1614 break;
1615
1616 case sizeof(GFC_INTEGER_8):
1617 memcpy (&i8, p, sizeof (i8));
1618 i = i8;
1619 break;
1620
1621 default:
1622 runtime_error ("Illegal value for record marker");
1623 break;
1624 }
1625 }
1626 else
1627 switch (nr)
1628 {
1629 case sizeof(GFC_INTEGER_4):
1630 reverse_memcpy (&i4, p, sizeof (i4));
1631 i = i4;
1632 break;
1633
1634 case sizeof(GFC_INTEGER_8):
1635 reverse_memcpy (&i8, p, sizeof (i8));
1636 i = i8;
1637 break;
1638
1639 default:
1640 runtime_error ("Illegal value for record marker");
1641 break;
1642 }
1643
1644 if (i >= 0)
1645 {
1646 dtp->u.p.current_unit->bytes_left_subrecord = i;
1647 dtp->u.p.current_unit->continued = 0;
1648 }
1649 else
1650 {
1651 dtp->u.p.current_unit->bytes_left_subrecord = -i;
1652 dtp->u.p.current_unit->continued = 1;
1653 }
1654
1655 if (! continued)
1656 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1657 }
1658
1659
1660 /* Preposition a sequential unformatted file while writing. This
1661 amount to writing a bogus length that will be filled in later. */
1662
1663 static void
1664 us_write (st_parameter_dt *dtp, int continued)
1665 {
1666 size_t nbytes;
1667 gfc_offset dummy;
1668
1669 dummy = 0;
1670
1671 if (compile_options.record_marker == 0)
1672 nbytes = sizeof (GFC_INTEGER_4);
1673 else
1674 nbytes = compile_options.record_marker ;
1675
1676 if (swrite (dtp->u.p.current_unit->s, &dummy, &nbytes) != 0)
1677 generate_error (&dtp->common, LIBERROR_OS, NULL);
1678
1679 /* For sequential unformatted, if RECL= was not specified in the OPEN
1680 we write until we have more bytes than can fit in the subrecord
1681 markers, then we write a new subrecord. */
1682
1683 dtp->u.p.current_unit->bytes_left_subrecord =
1684 dtp->u.p.current_unit->recl_subrecord;
1685 dtp->u.p.current_unit->continued = continued;
1686 }
1687
1688
1689 /* Position to the next record prior to transfer. We are assumed to
1690 be before the next record. We also calculate the bytes in the next
1691 record. */
1692
1693 static void
1694 pre_position (st_parameter_dt *dtp)
1695 {
1696 if (dtp->u.p.current_unit->current_record)
1697 return; /* Already positioned. */
1698
1699 switch (current_mode (dtp))
1700 {
1701 case FORMATTED_STREAM:
1702 case UNFORMATTED_STREAM:
1703 /* There are no records with stream I/O. Set the default position
1704 to the beginning of the file if no position was specified. */
1705 if ((dtp->common.flags & IOPARM_DT_HAS_REC) == 0)
1706 dtp->u.p.current_unit->strm_pos = 1;
1707 break;
1708
1709 case UNFORMATTED_SEQUENTIAL:
1710 if (dtp->u.p.mode == READING)
1711 us_read (dtp, 0);
1712 else
1713 us_write (dtp, 0);
1714
1715 break;
1716
1717 case FORMATTED_SEQUENTIAL:
1718 case FORMATTED_DIRECT:
1719 case UNFORMATTED_DIRECT:
1720 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1721 break;
1722 }
1723
1724 dtp->u.p.current_unit->current_record = 1;
1725 }
1726
1727
1728 /* Initialize things for a data transfer. This code is common for
1729 both reading and writing. */
1730
1731 static void
1732 data_transfer_init (st_parameter_dt *dtp, int read_flag)
1733 {
1734 unit_flags u_flags; /* Used for creating a unit if needed. */
1735 GFC_INTEGER_4 cf = dtp->common.flags;
1736 namelist_info *ionml;
1737
1738 ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL;
1739 memset (&dtp->u.p, 0, sizeof (dtp->u.p));
1740 dtp->u.p.ionml = ionml;
1741 dtp->u.p.mode = read_flag ? READING : WRITING;
1742
1743 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1744 return;
1745
1746 if ((cf & IOPARM_DT_HAS_SIZE) != 0)
1747 dtp->u.p.size_used = 0; /* Initialize the count. */
1748
1749 dtp->u.p.current_unit = get_unit (dtp, 1);
1750 if (dtp->u.p.current_unit->s == NULL)
1751 { /* Open the unit with some default flags. */
1752 st_parameter_open opp;
1753 unit_convert conv;
1754
1755 if (dtp->common.unit < 0)
1756 {
1757 close_unit (dtp->u.p.current_unit);
1758 dtp->u.p.current_unit = NULL;
1759 generate_error (&dtp->common, LIBERROR_BAD_OPTION,
1760 "Bad unit number in OPEN statement");
1761 return;
1762 }
1763 memset (&u_flags, '\0', sizeof (u_flags));
1764 u_flags.access = ACCESS_SEQUENTIAL;
1765 u_flags.action = ACTION_READWRITE;
1766
1767 /* Is it unformatted? */
1768 if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
1769 | IOPARM_DT_IONML_SET)))
1770 u_flags.form = FORM_UNFORMATTED;
1771 else
1772 u_flags.form = FORM_UNSPECIFIED;
1773
1774 u_flags.delim = DELIM_UNSPECIFIED;
1775 u_flags.blank = BLANK_UNSPECIFIED;
1776 u_flags.pad = PAD_UNSPECIFIED;
1777 u_flags.status = STATUS_UNKNOWN;
1778
1779 conv = get_unformatted_convert (dtp->common.unit);
1780
1781 if (conv == GFC_CONVERT_NONE)
1782 conv = compile_options.convert;
1783
1784 /* We use l8_to_l4_offset, which is 0 on little-endian machines
1785 and 1 on big-endian machines. */
1786 switch (conv)
1787 {
1788 case GFC_CONVERT_NATIVE:
1789 case GFC_CONVERT_SWAP:
1790 break;
1791
1792 case GFC_CONVERT_BIG:
1793 conv = l8_to_l4_offset ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
1794 break;
1795
1796 case GFC_CONVERT_LITTLE:
1797 conv = l8_to_l4_offset ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
1798 break;
1799
1800 default:
1801 internal_error (&opp.common, "Illegal value for CONVERT");
1802 break;
1803 }
1804
1805 u_flags.convert = conv;
1806
1807 opp.common = dtp->common;
1808 opp.common.flags &= IOPARM_COMMON_MASK;
1809 dtp->u.p.current_unit = new_unit (&opp, dtp->u.p.current_unit, &u_flags);
1810 dtp->common.flags &= ~IOPARM_COMMON_MASK;
1811 dtp->common.flags |= (opp.common.flags & IOPARM_COMMON_MASK);
1812 if (dtp->u.p.current_unit == NULL)
1813 return;
1814 }
1815
1816 /* Check the action. */
1817
1818 if (read_flag && dtp->u.p.current_unit->flags.action == ACTION_WRITE)
1819 {
1820 generate_error (&dtp->common, LIBERROR_BAD_ACTION,
1821 "Cannot read from file opened for WRITE");
1822 return;
1823 }
1824
1825 if (!read_flag && dtp->u.p.current_unit->flags.action == ACTION_READ)
1826 {
1827 generate_error (&dtp->common, LIBERROR_BAD_ACTION,
1828 "Cannot write to file opened for READ");
1829 return;
1830 }
1831
1832 dtp->u.p.first_item = 1;
1833
1834 /* Check the format. */
1835
1836 if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
1837 parse_format (dtp);
1838
1839 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
1840 && (cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
1841 != 0)
1842 {
1843 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1844 "Format present for UNFORMATTED data transfer");
1845 return;
1846 }
1847
1848 if ((cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0 && dtp->u.p.ionml != NULL)
1849 {
1850 if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
1851 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1852 "A format cannot be specified with a namelist");
1853 }
1854 else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
1855 !(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT)))
1856 {
1857 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1858 "Missing format for FORMATTED data transfer");
1859 }
1860
1861 if (is_internal_unit (dtp)
1862 && dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
1863 {
1864 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1865 "Internal file cannot be accessed by UNFORMATTED "
1866 "data transfer");
1867 return;
1868 }
1869
1870 /* Check the record or position number. */
1871
1872 if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT
1873 && (cf & IOPARM_DT_HAS_REC) == 0)
1874 {
1875 generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
1876 "Direct access data transfer requires record number");
1877 return;
1878 }
1879
1880 if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL
1881 && (cf & IOPARM_DT_HAS_REC) != 0)
1882 {
1883 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1884 "Record number not allowed for sequential access data transfer");
1885 return;
1886 }
1887
1888 /* Process the ADVANCE option. */
1889
1890 dtp->u.p.advance_status
1891 = !(cf & IOPARM_DT_HAS_ADVANCE) ? ADVANCE_UNSPECIFIED :
1892 find_option (&dtp->common, dtp->advance, dtp->advance_len, advance_opt,
1893 "Bad ADVANCE parameter in data transfer statement");
1894
1895 if (dtp->u.p.advance_status != ADVANCE_UNSPECIFIED)
1896 {
1897 if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
1898 {
1899 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1900 "ADVANCE specification conflicts with sequential access");
1901 return;
1902 }
1903
1904 if (is_internal_unit (dtp))
1905 {
1906 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1907 "ADVANCE specification conflicts with internal file");
1908 return;
1909 }
1910
1911 if ((cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
1912 != IOPARM_DT_HAS_FORMAT)
1913 {
1914 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1915 "ADVANCE specification requires an explicit format");
1916 return;
1917 }
1918 }
1919
1920 if (read_flag)
1921 {
1922 dtp->u.p.current_unit->previous_nonadvancing_write = 0;
1923
1924 if ((cf & IOPARM_EOR) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
1925 {
1926 generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
1927 "EOR specification requires an ADVANCE specification "
1928 "of NO");
1929 return;
1930 }
1931
1932 if ((cf & IOPARM_DT_HAS_SIZE) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
1933 {
1934 generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
1935 "SIZE specification requires an ADVANCE specification of NO");
1936 return;
1937 }
1938 }
1939 else
1940 { /* Write constraints. */
1941 if ((cf & IOPARM_END) != 0)
1942 {
1943 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1944 "END specification cannot appear in a write statement");
1945 return;
1946 }
1947
1948 if ((cf & IOPARM_EOR) != 0)
1949 {
1950 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1951 "EOR specification cannot appear in a write statement");
1952 return;
1953 }
1954
1955 if ((cf & IOPARM_DT_HAS_SIZE) != 0)
1956 {
1957 generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
1958 "SIZE specification cannot appear in a write statement");
1959 return;
1960 }
1961 }
1962
1963 if (dtp->u.p.advance_status == ADVANCE_UNSPECIFIED)
1964 dtp->u.p.advance_status = ADVANCE_YES;
1965
1966 /* Sanity checks on the record number. */
1967 if ((cf & IOPARM_DT_HAS_REC) != 0)
1968 {
1969 if (dtp->rec <= 0)
1970 {
1971 generate_error (&dtp->common, LIBERROR_BAD_OPTION,
1972 "Record number must be positive");
1973 return;
1974 }
1975
1976 if (dtp->rec >= dtp->u.p.current_unit->maxrec)
1977 {
1978 generate_error (&dtp->common, LIBERROR_BAD_OPTION,
1979 "Record number too large");
1980 return;
1981 }
1982
1983 /* Check to see if we might be reading what we wrote before */
1984
1985 if (dtp->u.p.mode == READING
1986 && dtp->u.p.current_unit->mode == WRITING
1987 && !is_internal_unit (dtp))
1988 flush(dtp->u.p.current_unit->s);
1989
1990 /* Check whether the record exists to be read. Only
1991 a partial record needs to exist. */
1992
1993 if (dtp->u.p.mode == READING && (dtp->rec -1)
1994 * dtp->u.p.current_unit->recl >= file_length (dtp->u.p.current_unit->s))
1995 {
1996 generate_error (&dtp->common, LIBERROR_BAD_OPTION,
1997 "Non-existing record number");
1998 return;
1999 }
2000
2001 /* Position the file. */
2002 if (!is_stream_io (dtp))
2003 {
2004 if (sseek (dtp->u.p.current_unit->s, (gfc_offset) (dtp->rec - 1)
2005 * dtp->u.p.current_unit->recl) == FAILURE)
2006 {
2007 generate_error (&dtp->common, LIBERROR_OS, NULL);
2008 return;
2009 }
2010 }
2011 else
2012 dtp->u.p.current_unit->strm_pos = dtp->rec;
2013
2014 }
2015 else
2016 dtp->rec = 0;
2017
2018 /* Overwriting an existing sequential file ?
2019 it is always safe to truncate the file on the first write */
2020 if (dtp->u.p.mode == WRITING
2021 && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL
2022 && dtp->u.p.current_unit->last_record == 0
2023 && !is_preconnected(dtp->u.p.current_unit->s))
2024 struncate(dtp->u.p.current_unit->s);
2025
2026 /* Bugware for badly written mixed C-Fortran I/O. */
2027 flush_if_preconnected(dtp->u.p.current_unit->s);
2028
2029 dtp->u.p.current_unit->mode = dtp->u.p.mode;
2030
2031 /* Set the initial value of flags. */
2032
2033 dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;
2034 dtp->u.p.sign_status = SIGN_S;
2035
2036 /* Set the maximum position reached from the previous I/O operation. This
2037 could be greater than zero from a previous non-advancing write. */
2038 dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
2039
2040 pre_position (dtp);
2041
2042 /* Set up the subroutine that will handle the transfers. */
2043
2044 if (read_flag)
2045 {
2046 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
2047 dtp->u.p.transfer = unformatted_read;
2048 else
2049 {
2050 if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
2051 dtp->u.p.transfer = list_formatted_read;
2052 else
2053 dtp->u.p.transfer = formatted_transfer;
2054 }
2055 }
2056 else
2057 {
2058 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
2059 dtp->u.p.transfer = unformatted_write;
2060 else
2061 {
2062 if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
2063 dtp->u.p.transfer = list_formatted_write;
2064 else
2065 dtp->u.p.transfer = formatted_transfer;
2066 }
2067 }
2068
2069 /* Make sure that we don't do a read after a nonadvancing write. */
2070
2071 if (read_flag)
2072 {
2073 if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
2074 {
2075 generate_error (&dtp->common, LIBERROR_BAD_OPTION,
2076 "Cannot READ after a nonadvancing WRITE");
2077 return;
2078 }
2079 }
2080 else
2081 {
2082 if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
2083 dtp->u.p.current_unit->read_bad = 1;
2084 }
2085
2086 /* Start the data transfer if we are doing a formatted transfer. */
2087 if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
2088 && ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0)
2089 && dtp->u.p.ionml == NULL)
2090 formatted_transfer (dtp, 0, NULL, 0, 0, 1);
2091 }
2092
2093 /* Initialize an array_loop_spec given the array descriptor. The function
2094 returns the index of the last element of the array, and also returns
2095 starting record, where the first I/O goes to (necessary in case of
2096 negative strides). */
2097
2098 gfc_offset
2099 init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
2100 gfc_offset *start_record)
2101 {
2102 int rank = GFC_DESCRIPTOR_RANK(desc);
2103 int i;
2104 gfc_offset index;
2105 int empty;
2106
2107 empty = 0;
2108 index = 1;
2109 *start_record = 0;
2110
2111 for (i=0; i<rank; i++)
2112 {
2113 ls[i].idx = desc->dim[i].lbound;
2114 ls[i].start = desc->dim[i].lbound;
2115 ls[i].end = desc->dim[i].ubound;
2116 ls[i].step = desc->dim[i].stride;
2117 empty = empty || (desc->dim[i].ubound < desc->dim[i].lbound);
2118
2119 if (desc->dim[i].stride > 0)
2120 {
2121 index += (desc->dim[i].ubound - desc->dim[i].lbound)
2122 * desc->dim[i].stride;
2123 }
2124 else
2125 {
2126 index -= (desc->dim[i].ubound - desc->dim[i].lbound)
2127 * desc->dim[i].stride;
2128 *start_record -= (desc->dim[i].ubound - desc->dim[i].lbound)
2129 * desc->dim[i].stride;
2130 }
2131 }
2132
2133 if (empty)
2134 return 0;
2135 else
2136 return index;
2137 }
2138
2139 /* Determine the index to the next record in an internal unit array by
2140 by incrementing through the array_loop_spec. */
2141
2142 gfc_offset
2143 next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
2144 {
2145 int i, carry;
2146 gfc_offset index;
2147
2148 carry = 1;
2149 index = 0;
2150
2151 for (i = 0; i < dtp->u.p.current_unit->rank; i++)
2152 {
2153 if (carry)
2154 {
2155 ls[i].idx++;
2156 if (ls[i].idx > ls[i].end)
2157 {
2158 ls[i].idx = ls[i].start;
2159 carry = 1;
2160 }
2161 else
2162 carry = 0;
2163 }
2164 index = index + (ls[i].idx - ls[i].start) * ls[i].step;
2165 }
2166
2167 *finished = carry;
2168
2169 return index;
2170 }
2171
2172
2173
2174 /* Skip to the end of the current record, taking care of an optional
2175 record marker of size bytes. If the file is not seekable, we
2176 read chunks of size MAX_READ until we get to the right
2177 position. */
2178
2179 #define MAX_READ 4096
2180
2181 static void
2182 skip_record (st_parameter_dt *dtp, size_t bytes)
2183 {
2184 gfc_offset new;
2185 int rlength, length;
2186 char *p;
2187
2188 dtp->u.p.current_unit->bytes_left_subrecord += bytes;
2189 if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
2190 return;
2191
2192 if (is_seekable (dtp->u.p.current_unit->s))
2193 {
2194 new = file_position (dtp->u.p.current_unit->s)
2195 + dtp->u.p.current_unit->bytes_left_subrecord;
2196
2197 /* Direct access files do not generate END conditions,
2198 only I/O errors. */
2199 if (sseek (dtp->u.p.current_unit->s, new) == FAILURE)
2200 generate_error (&dtp->common, LIBERROR_OS, NULL);
2201 }
2202 else
2203 { /* Seek by reading data. */
2204 while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
2205 {
2206 rlength = length =
2207 (MAX_READ > dtp->u.p.current_unit->bytes_left_subrecord) ?
2208 MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
2209
2210 p = salloc_r (dtp->u.p.current_unit->s, &rlength);
2211 if (p == NULL)
2212 {
2213 generate_error (&dtp->common, LIBERROR_OS, NULL);
2214 return;
2215 }
2216
2217 dtp->u.p.current_unit->bytes_left_subrecord -= length;
2218 }
2219 }
2220
2221 }
2222
2223 #undef MAX_READ
2224
2225 /* Advance to the next record reading unformatted files, taking
2226 care of subrecords. If complete_record is nonzero, we loop
2227 until all subrecords are cleared. */
2228
2229 static void
2230 next_record_r_unf (st_parameter_dt *dtp, int complete_record)
2231 {
2232 size_t bytes;
2233
2234 bytes = compile_options.record_marker == 0 ?
2235 sizeof (GFC_INTEGER_4) : compile_options.record_marker;
2236
2237 while(1)
2238 {
2239
2240 /* Skip over tail */
2241
2242 skip_record (dtp, bytes);
2243
2244 if ( ! (complete_record && dtp->u.p.current_unit->continued))
2245 return;
2246
2247 us_read (dtp, 1);
2248 }
2249 }
2250
2251 /* Space to the next record for read mode. */
2252
2253 static void
2254 next_record_r (st_parameter_dt *dtp)
2255 {
2256 gfc_offset record;
2257 int length, bytes_left;
2258 char *p;
2259
2260 switch (current_mode (dtp))
2261 {
2262 /* No records in unformatted STREAM I/O. */
2263 case UNFORMATTED_STREAM:
2264 return;
2265
2266 case UNFORMATTED_SEQUENTIAL:
2267 next_record_r_unf (dtp, 1);
2268 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2269 break;
2270
2271 case FORMATTED_DIRECT:
2272 case UNFORMATTED_DIRECT:
2273 skip_record (dtp, 0);
2274 break;
2275
2276 case FORMATTED_STREAM:
2277 case FORMATTED_SEQUENTIAL:
2278 length = 1;
2279 /* sf_read has already terminated input because of an '\n' */
2280 if (dtp->u.p.sf_seen_eor)
2281 {
2282 dtp->u.p.sf_seen_eor = 0;
2283 break;
2284 }
2285
2286 if (is_internal_unit (dtp))
2287 {
2288 if (is_array_io (dtp))
2289 {
2290 int finished;
2291
2292 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
2293 &finished);
2294
2295 /* Now seek to this record. */
2296 record = record * dtp->u.p.current_unit->recl;
2297 if (sseek (dtp->u.p.current_unit->s, record) == FAILURE)
2298 {
2299 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
2300 break;
2301 }
2302 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2303 }
2304 else
2305 {
2306 bytes_left = (int) dtp->u.p.current_unit->bytes_left;
2307 p = salloc_r (dtp->u.p.current_unit->s, &bytes_left);
2308 if (p != NULL)
2309 dtp->u.p.current_unit->bytes_left
2310 = dtp->u.p.current_unit->recl;
2311 }
2312 break;
2313 }
2314 else do
2315 {
2316 p = salloc_r (dtp->u.p.current_unit->s, &length);
2317
2318 if (p == NULL)
2319 {
2320 generate_error (&dtp->common, LIBERROR_OS, NULL);
2321 break;
2322 }
2323
2324 if (length == 0)
2325 {
2326 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2327 break;
2328 }
2329
2330 if (is_stream_io (dtp))
2331 dtp->u.p.current_unit->strm_pos++;
2332 }
2333 while (*p != '\n');
2334
2335 break;
2336 }
2337
2338 if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL
2339 && !dtp->u.p.namelist_mode
2340 && dtp->u.p.current_unit->endfile == NO_ENDFILE
2341 && (file_length (dtp->u.p.current_unit->s) ==
2342 file_position (dtp->u.p.current_unit->s)))
2343 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2344
2345 }
2346
2347
2348 /* Small utility function to write a record marker, taking care of
2349 byte swapping and of choosing the correct size. */
2350
2351 inline static int
2352 write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
2353 {
2354 size_t len;
2355 GFC_INTEGER_4 buf4;
2356 GFC_INTEGER_8 buf8;
2357 char p[sizeof (GFC_INTEGER_8)];
2358
2359 if (compile_options.record_marker == 0)
2360 len = sizeof (GFC_INTEGER_4);
2361 else
2362 len = compile_options.record_marker;
2363
2364 /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
2365 if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
2366 {
2367 switch (len)
2368 {
2369 case sizeof (GFC_INTEGER_4):
2370 buf4 = buf;
2371 return swrite (dtp->u.p.current_unit->s, &buf4, &len);
2372 break;
2373
2374 case sizeof (GFC_INTEGER_8):
2375 buf8 = buf;
2376 return swrite (dtp->u.p.current_unit->s, &buf8, &len);
2377 break;
2378
2379 default:
2380 runtime_error ("Illegal value for record marker");
2381 break;
2382 }
2383 }
2384 else
2385 {
2386 switch (len)
2387 {
2388 case sizeof (GFC_INTEGER_4):
2389 buf4 = buf;
2390 reverse_memcpy (p, &buf4, sizeof (GFC_INTEGER_4));
2391 return swrite (dtp->u.p.current_unit->s, p, &len);
2392 break;
2393
2394 case sizeof (GFC_INTEGER_8):
2395 buf8 = buf;
2396 reverse_memcpy (p, &buf8, sizeof (GFC_INTEGER_8));
2397 return swrite (dtp->u.p.current_unit->s, p, &len);
2398 break;
2399
2400 default:
2401 runtime_error ("Illegal value for record marker");
2402 break;
2403 }
2404 }
2405
2406 }
2407
2408 /* Position to the next (sub)record in write mode for
2409 unformatted sequential files. */
2410
2411 static void
2412 next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
2413 {
2414 gfc_offset c, m, m_write;
2415 size_t record_marker;
2416
2417 /* Bytes written. */
2418 m = dtp->u.p.current_unit->recl_subrecord
2419 - dtp->u.p.current_unit->bytes_left_subrecord;
2420 c = file_position (dtp->u.p.current_unit->s);
2421
2422 /* Write the length tail. If we finish a record containing
2423 subrecords, we write out the negative length. */
2424
2425 if (dtp->u.p.current_unit->continued)
2426 m_write = -m;
2427 else
2428 m_write = m;
2429
2430 if (write_us_marker (dtp, m_write) != 0)
2431 goto io_error;
2432
2433 if (compile_options.record_marker == 0)
2434 record_marker = sizeof (GFC_INTEGER_4);
2435 else
2436 record_marker = compile_options.record_marker;
2437
2438 /* Seek to the head and overwrite the bogus length with the real
2439 length. */
2440
2441 if (sseek (dtp->u.p.current_unit->s, c - m - record_marker)
2442 == FAILURE)
2443 goto io_error;
2444
2445 if (next_subrecord)
2446 m_write = -m;
2447 else
2448 m_write = m;
2449
2450 if (write_us_marker (dtp, m_write) != 0)
2451 goto io_error;
2452
2453 /* Seek past the end of the current record. */
2454
2455 if (sseek (dtp->u.p.current_unit->s, c + record_marker) == FAILURE)
2456 goto io_error;
2457
2458 return;
2459
2460 io_error:
2461 generate_error (&dtp->common, LIBERROR_OS, NULL);
2462 return;
2463
2464 }
2465
2466 /* Position to the next record in write mode. */
2467
2468 static void
2469 next_record_w (st_parameter_dt *dtp, int done)
2470 {
2471 gfc_offset m, record, max_pos;
2472 int length;
2473 char *p;
2474
2475 /* Zero counters for X- and T-editing. */
2476 max_pos = dtp->u.p.max_pos;
2477 dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2478
2479 switch (current_mode (dtp))
2480 {
2481 /* No records in unformatted STREAM I/O. */
2482 case UNFORMATTED_STREAM:
2483 return;
2484
2485 case FORMATTED_DIRECT:
2486 if (dtp->u.p.current_unit->bytes_left == 0)
2487 break;
2488
2489 if (sset (dtp->u.p.current_unit->s, ' ',
2490 dtp->u.p.current_unit->bytes_left) == FAILURE)
2491 goto io_error;
2492
2493 break;
2494
2495 case UNFORMATTED_DIRECT:
2496 if (sfree (dtp->u.p.current_unit->s) == FAILURE)
2497 goto io_error;
2498 break;
2499
2500 case UNFORMATTED_SEQUENTIAL:
2501 next_record_w_unf (dtp, 0);
2502 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2503 break;
2504
2505 case FORMATTED_STREAM:
2506 case FORMATTED_SEQUENTIAL:
2507
2508 if (is_internal_unit (dtp))
2509 {
2510 if (is_array_io (dtp))
2511 {
2512 int finished;
2513
2514 length = (int) dtp->u.p.current_unit->bytes_left;
2515
2516 /* If the farthest position reached is greater than current
2517 position, adjust the position and set length to pad out
2518 whats left. Otherwise just pad whats left.
2519 (for character array unit) */
2520 m = dtp->u.p.current_unit->recl
2521 - dtp->u.p.current_unit->bytes_left;
2522 if (max_pos > m)
2523 {
2524 length = (int) (max_pos - m);
2525 p = salloc_w (dtp->u.p.current_unit->s, &length);
2526 length = (int) (dtp->u.p.current_unit->recl - max_pos);
2527 }
2528
2529 if (sset (dtp->u.p.current_unit->s, ' ', length) == FAILURE)
2530 {
2531 generate_error (&dtp->common, LIBERROR_END, NULL);
2532 return;
2533 }
2534
2535 /* Now that the current record has been padded out,
2536 determine where the next record in the array is. */
2537 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
2538 &finished);
2539 if (finished)
2540 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2541
2542 /* Now seek to this record */
2543 record = record * dtp->u.p.current_unit->recl;
2544
2545 if (sseek (dtp->u.p.current_unit->s, record) == FAILURE)
2546 {
2547 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
2548 return;
2549 }
2550
2551 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2552 }
2553 else
2554 {
2555 length = 1;
2556
2557 /* If this is the last call to next_record move to the farthest
2558 position reached and set length to pad out the remainder
2559 of the record. (for character scaler unit) */
2560 if (done)
2561 {
2562 m = dtp->u.p.current_unit->recl
2563 - dtp->u.p.current_unit->bytes_left;
2564 if (max_pos > m)
2565 {
2566 length = (int) (max_pos - m);
2567 p = salloc_w (dtp->u.p.current_unit->s, &length);
2568 length = (int) (dtp->u.p.current_unit->recl - max_pos);
2569 }
2570 else
2571 length = (int) dtp->u.p.current_unit->bytes_left;
2572 }
2573
2574 if (sset (dtp->u.p.current_unit->s, ' ', length) == FAILURE)
2575 {
2576 generate_error (&dtp->common, LIBERROR_END, NULL);
2577 return;
2578 }
2579 }
2580 }
2581 else
2582 {
2583 size_t len;
2584 const char crlf[] = "\r\n";
2585
2586 /* Move to the farthest position reached in preparation for
2587 completing the record. (for file unit) */
2588 m = dtp->u.p.current_unit->recl -
2589 dtp->u.p.current_unit->bytes_left;
2590 if (max_pos > m)
2591 {
2592 length = (int) (max_pos - m);
2593 sseek (dtp->u.p.current_unit->s,
2594 file_position (dtp->u.p.current_unit->s) + length);
2595 }
2596 #ifdef HAVE_CRLF
2597 len = 2;
2598 #else
2599 len = 1;
2600 #endif
2601 if (swrite (dtp->u.p.current_unit->s, &crlf[2-len], &len) != 0)
2602 goto io_error;
2603
2604 if (is_stream_io (dtp))
2605 {
2606 dtp->u.p.current_unit->strm_pos += len;
2607 struncate(dtp->u.p.current_unit->s);
2608 }
2609 }
2610
2611 break;
2612
2613 io_error:
2614 generate_error (&dtp->common, LIBERROR_OS, NULL);
2615 break;
2616 }
2617 }
2618
2619 /* Position to the next record, which means moving to the end of the
2620 current record. This can happen under several different
2621 conditions. If the done flag is not set, we get ready to process
2622 the next record. */
2623
2624 void
2625 next_record (st_parameter_dt *dtp, int done)
2626 {
2627 gfc_offset fp; /* File position. */
2628
2629 dtp->u.p.current_unit->read_bad = 0;
2630
2631 if (dtp->u.p.mode == READING)
2632 next_record_r (dtp);
2633 else
2634 next_record_w (dtp, done);
2635
2636 if (!is_stream_io (dtp))
2637 {
2638 /* Keep position up to date for INQUIRE */
2639 if (done)
2640 update_position (dtp->u.p.current_unit);
2641
2642 dtp->u.p.current_unit->current_record = 0;
2643 if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
2644 {
2645 fp = file_position (dtp->u.p.current_unit->s);
2646 /* Calculate next record, rounding up partial records. */
2647 dtp->u.p.current_unit->last_record =
2648 (fp + dtp->u.p.current_unit->recl - 1) /
2649 dtp->u.p.current_unit->recl;
2650 }
2651 else
2652 dtp->u.p.current_unit->last_record++;
2653 }
2654
2655 if (!done)
2656 pre_position (dtp);
2657 }
2658
2659
2660 /* Finalize the current data transfer. For a nonadvancing transfer,
2661 this means advancing to the next record. For internal units close the
2662 stream associated with the unit. */
2663
2664 static void
2665 finalize_transfer (st_parameter_dt *dtp)
2666 {
2667 jmp_buf eof_jump;
2668 GFC_INTEGER_4 cf = dtp->common.flags;
2669
2670 if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
2671 *dtp->size = (GFC_IO_INT) dtp->u.p.size_used;
2672
2673 if (dtp->u.p.eor_condition)
2674 {
2675 generate_error (&dtp->common, LIBERROR_EOR, NULL);
2676 return;
2677 }
2678
2679 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2680 return;
2681
2682 if ((dtp->u.p.ionml != NULL)
2683 && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
2684 {
2685 if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
2686 namelist_read (dtp);
2687 else
2688 namelist_write (dtp);
2689 }
2690
2691 dtp->u.p.transfer = NULL;
2692 if (dtp->u.p.current_unit == NULL)
2693 return;
2694
2695 dtp->u.p.eof_jump = &eof_jump;
2696 if (setjmp (eof_jump))
2697 {
2698 generate_error (&dtp->common, LIBERROR_END, NULL);
2699 return;
2700 }
2701
2702 if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
2703 {
2704 finish_list_read (dtp);
2705 sfree (dtp->u.p.current_unit->s);
2706 return;
2707 }
2708
2709 if (dtp->u.p.mode == WRITING)
2710 dtp->u.p.current_unit->previous_nonadvancing_write
2711 = dtp->u.p.advance_status == ADVANCE_NO;
2712
2713 if (is_stream_io (dtp))
2714 {
2715 if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
2716 && dtp->u.p.advance_status != ADVANCE_NO)
2717 next_record (dtp, 1);
2718
2719 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
2720 && file_position (dtp->u.p.current_unit->s) >= dtp->rec)
2721 {
2722 flush (dtp->u.p.current_unit->s);
2723 sfree (dtp->u.p.current_unit->s);
2724 }
2725 return;
2726 }
2727
2728 dtp->u.p.current_unit->current_record = 0;
2729
2730 if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
2731 {
2732 dtp->u.p.seen_dollar = 0;
2733 sfree (dtp->u.p.current_unit->s);
2734 return;
2735 }
2736
2737 /* For non-advancing I/O, save the current maximum position for use in the
2738 next I/O operation if needed. */
2739 if (dtp->u.p.advance_status == ADVANCE_NO)
2740 {
2741 int bytes_written = (int) (dtp->u.p.current_unit->recl
2742 - dtp->u.p.current_unit->bytes_left);
2743 dtp->u.p.current_unit->saved_pos =
2744 dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
2745 flush (dtp->u.p.current_unit->s);
2746 return;
2747 }
2748
2749 dtp->u.p.current_unit->saved_pos = 0;
2750
2751 next_record (dtp, 1);
2752 sfree (dtp->u.p.current_unit->s);
2753 }
2754
2755 /* Transfer function for IOLENGTH. It doesn't actually do any
2756 data transfer, it just updates the length counter. */
2757
2758 static void
2759 iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
2760 void *dest __attribute__ ((unused)),
2761 int kind __attribute__((unused)),
2762 size_t size, size_t nelems)
2763 {
2764 if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
2765 *dtp->iolength += (GFC_IO_INT) size * nelems;
2766 }
2767
2768
2769 /* Initialize the IOLENGTH data transfer. This function is in essence
2770 a very much simplified version of data_transfer_init(), because it
2771 doesn't have to deal with units at all. */
2772
2773 static void
2774 iolength_transfer_init (st_parameter_dt *dtp)
2775 {
2776 if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
2777 *dtp->iolength = 0;
2778
2779 memset (&dtp->u.p, 0, sizeof (dtp->u.p));
2780
2781 /* Set up the subroutine that will handle the transfers. */
2782
2783 dtp->u.p.transfer = iolength_transfer;
2784 }
2785
2786
2787 /* Library entry point for the IOLENGTH form of the INQUIRE
2788 statement. The IOLENGTH form requires no I/O to be performed, but
2789 it must still be a runtime library call so that we can determine
2790 the iolength for dynamic arrays and such. */
2791
2792 extern void st_iolength (st_parameter_dt *);
2793 export_proto(st_iolength);
2794
2795 void
2796 st_iolength (st_parameter_dt *dtp)
2797 {
2798 library_start (&dtp->common);
2799 iolength_transfer_init (dtp);
2800 }
2801
2802 extern void st_iolength_done (st_parameter_dt *);
2803 export_proto(st_iolength_done);
2804
2805 void
2806 st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
2807 {
2808 free_ionml (dtp);
2809 if (dtp->u.p.scratch != NULL)
2810 free_mem (dtp->u.p.scratch);
2811 library_end ();
2812 }
2813
2814
2815 /* The READ statement. */
2816
2817 extern void st_read (st_parameter_dt *);
2818 export_proto(st_read);
2819
2820 void
2821 st_read (st_parameter_dt *dtp)
2822 {
2823 library_start (&dtp->common);
2824
2825 data_transfer_init (dtp, 1);
2826
2827 /* Handle complications dealing with the endfile record. */
2828
2829 if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
2830 switch (dtp->u.p.current_unit->endfile)
2831 {
2832 case NO_ENDFILE:
2833 break;
2834
2835 case AT_ENDFILE:
2836 if (!is_internal_unit (dtp))
2837 {
2838 generate_error (&dtp->common, LIBERROR_END, NULL);
2839 dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
2840 dtp->u.p.current_unit->current_record = 0;
2841 }
2842 break;
2843
2844 case AFTER_ENDFILE:
2845 generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
2846 dtp->u.p.current_unit->current_record = 0;
2847 break;
2848 }
2849 }
2850
2851 extern void st_read_done (st_parameter_dt *);
2852 export_proto(st_read_done);
2853
2854 void
2855 st_read_done (st_parameter_dt *dtp)
2856 {
2857 finalize_transfer (dtp);
2858 free_format_data (dtp);
2859 free_ionml (dtp);
2860 if (dtp->u.p.scratch != NULL)
2861 free_mem (dtp->u.p.scratch);
2862 if (dtp->u.p.current_unit != NULL)
2863 unlock_unit (dtp->u.p.current_unit);
2864
2865 free_internal_unit (dtp);
2866
2867 library_end ();
2868 }
2869
2870 extern void st_write (st_parameter_dt *);
2871 export_proto(st_write);
2872
2873 void
2874 st_write (st_parameter_dt *dtp)
2875 {
2876 library_start (&dtp->common);
2877 data_transfer_init (dtp, 0);
2878 }
2879
2880 extern void st_write_done (st_parameter_dt *);
2881 export_proto(st_write_done);
2882
2883 void
2884 st_write_done (st_parameter_dt *dtp)
2885 {
2886 finalize_transfer (dtp);
2887
2888 /* Deal with endfile conditions associated with sequential files. */
2889
2890 if (dtp->u.p.current_unit != NULL
2891 && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
2892 switch (dtp->u.p.current_unit->endfile)
2893 {
2894 case AT_ENDFILE: /* Remain at the endfile record. */
2895 break;
2896
2897 case AFTER_ENDFILE:
2898 dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now. */
2899 break;
2900
2901 case NO_ENDFILE:
2902 /* Get rid of whatever is after this record. */
2903 if (!is_internal_unit (dtp))
2904 {
2905 flush (dtp->u.p.current_unit->s);
2906 if (struncate (dtp->u.p.current_unit->s) == FAILURE)
2907 generate_error (&dtp->common, LIBERROR_OS, NULL);
2908 }
2909 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2910 break;
2911 }
2912
2913 free_format_data (dtp);
2914 free_ionml (dtp);
2915 if (dtp->u.p.scratch != NULL)
2916 free_mem (dtp->u.p.scratch);
2917 if (dtp->u.p.current_unit != NULL)
2918 unlock_unit (dtp->u.p.current_unit);
2919
2920 free_internal_unit (dtp);
2921
2922 library_end ();
2923 }
2924
2925 /* Receives the scalar information for namelist objects and stores it
2926 in a linked list of namelist_info types. */
2927
2928 extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
2929 GFC_INTEGER_4, gfc_charlen_type, GFC_INTEGER_4);
2930 export_proto(st_set_nml_var);
2931
2932
2933 void
2934 st_set_nml_var (st_parameter_dt *dtp, void * var_addr, char * var_name,
2935 GFC_INTEGER_4 len, gfc_charlen_type string_length,
2936 GFC_INTEGER_4 dtype)
2937 {
2938 namelist_info *t1 = NULL;
2939 namelist_info *nml;
2940 size_t var_name_len = strlen (var_name);
2941
2942 nml = (namelist_info*) get_mem (sizeof (namelist_info));
2943
2944 nml->mem_pos = var_addr;
2945
2946 nml->var_name = (char*) get_mem (var_name_len + 1);
2947 memcpy (nml->var_name, var_name, var_name_len);
2948 nml->var_name[var_name_len] = '\0';
2949
2950 nml->len = (int) len;
2951 nml->string_length = (index_type) string_length;
2952
2953 nml->var_rank = (int) (dtype & GFC_DTYPE_RANK_MASK);
2954 nml->size = (index_type) (dtype >> GFC_DTYPE_SIZE_SHIFT);
2955 nml->type = (bt) ((dtype & GFC_DTYPE_TYPE_MASK) >> GFC_DTYPE_TYPE_SHIFT);
2956
2957 if (nml->var_rank > 0)
2958 {
2959 nml->dim = (descriptor_dimension*)
2960 get_mem (nml->var_rank * sizeof (descriptor_dimension));
2961 nml->ls = (array_loop_spec*)
2962 get_mem (nml->var_rank * sizeof (array_loop_spec));
2963 }
2964 else
2965 {
2966 nml->dim = NULL;
2967 nml->ls = NULL;
2968 }
2969
2970 nml->next = NULL;
2971
2972 if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
2973 {
2974 dtp->common.flags |= IOPARM_DT_IONML_SET;
2975 dtp->u.p.ionml = nml;
2976 }
2977 else
2978 {
2979 for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
2980 t1->next = nml;
2981 }
2982 }
2983
2984 /* Store the dimensional information for the namelist object. */
2985 extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
2986 index_type, index_type,
2987 index_type);
2988 export_proto(st_set_nml_var_dim);
2989
2990 void
2991 st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
2992 index_type stride, index_type lbound,
2993 index_type ubound)
2994 {
2995 namelist_info * nml;
2996 int n;
2997
2998 n = (int)n_dim;
2999
3000 for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);
3001
3002 nml->dim[n].stride = stride;
3003 nml->dim[n].lbound = lbound;
3004 nml->dim[n].ubound = ubound;
3005 }
3006
3007 /* Reverse memcpy - used for byte swapping. */
3008
3009 void reverse_memcpy (void *dest, const void *src, size_t n)
3010 {
3011 char *d, *s;
3012 size_t i;
3013
3014 d = (char *) dest;
3015 s = (char *) src + n - 1;
3016
3017 /* Write with ascending order - this is likely faster
3018 on modern architectures because of write combining. */
3019 for (i=0; i<n; i++)
3020 *(d++) = *(s--);
3021 }