re PR fortran/35699 (run-time abort writing zero sized section to direct access file)
[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 return SUCCESS;
643
644 if (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0)
645 {
646 generate_error (&dtp->common, LIBERROR_OS, NULL);
647 return FAILURE;
648 }
649
650 dtp->u.p.current_unit->strm_pos += (gfc_offset) nbytes;
651 dtp->u.p.current_unit->bytes_left -= (gfc_offset) nbytes;
652
653 return SUCCESS;
654 }
655
656 /* Unformatted sequential. */
657
658 have_written = 0;
659
660 if (dtp->u.p.current_unit->flags.has_recl
661 && (gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left)
662 {
663 nbytes = dtp->u.p.current_unit->bytes_left;
664 short_record = 1;
665 }
666 else
667 {
668 short_record = 0;
669 }
670
671 while (1)
672 {
673
674 to_write_subrecord =
675 (size_t) dtp->u.p.current_unit->bytes_left_subrecord < nbytes ?
676 (size_t) dtp->u.p.current_unit->bytes_left_subrecord : nbytes;
677
678 dtp->u.p.current_unit->bytes_left_subrecord -=
679 (gfc_offset) to_write_subrecord;
680
681 if (swrite (dtp->u.p.current_unit->s, buf + have_written,
682 &to_write_subrecord) != 0)
683 {
684 generate_error (&dtp->common, LIBERROR_OS, NULL);
685 return FAILURE;
686 }
687
688 dtp->u.p.current_unit->strm_pos += (gfc_offset) to_write_subrecord;
689 nbytes -= to_write_subrecord;
690 have_written += to_write_subrecord;
691
692 if (nbytes == 0)
693 break;
694
695 next_record_w_unf (dtp, 1);
696 us_write (dtp, 1);
697 }
698 dtp->u.p.current_unit->bytes_left -= have_written;
699 if (short_record)
700 {
701 generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
702 return FAILURE;
703 }
704 return SUCCESS;
705 }
706
707
708 /* Master function for unformatted reads. */
709
710 static void
711 unformatted_read (st_parameter_dt *dtp, bt type,
712 void *dest, int kind __attribute__((unused)),
713 size_t size, size_t nelems)
714 {
715 size_t i, sz;
716
717 /* Currently, character implies size=1. */
718 if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE
719 || size == 1 || type == BT_CHARACTER)
720 {
721 sz = size * nelems;
722 read_block_direct (dtp, dest, &sz);
723 }
724 else
725 {
726 char buffer[16];
727 char *p;
728
729 /* Break up complex into its constituent reals. */
730 if (type == BT_COMPLEX)
731 {
732 nelems *= 2;
733 size /= 2;
734 }
735 p = dest;
736
737 /* By now, all complex variables have been split into their
738 constituent reals. */
739
740 for (i=0; i<nelems; i++)
741 {
742 read_block_direct (dtp, buffer, &size);
743 reverse_memcpy (p, buffer, size);
744 p += size;
745 }
746 }
747 }
748
749
750 /* Master function for unformatted writes. NOTE: For kind=10 the size is 16
751 bytes on 64 bit machines. The unused bytes are not initialized and never
752 used, which can show an error with memory checking analyzers like
753 valgrind. */
754
755 static void
756 unformatted_write (st_parameter_dt *dtp, bt type,
757 void *source, int kind __attribute__((unused)),
758 size_t size, size_t nelems)
759 {
760 if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE ||
761 size == 1 || type == BT_CHARACTER)
762 {
763 size *= nelems;
764 write_buf (dtp, source, size);
765 }
766 else
767 {
768 char buffer[16];
769 char *p;
770 size_t i;
771
772 /* Break up complex into its constituent reals. */
773 if (type == BT_COMPLEX)
774 {
775 nelems *= 2;
776 size /= 2;
777 }
778
779 p = source;
780
781 /* By now, all complex variables have been split into their
782 constituent reals. */
783
784
785 for (i=0; i<nelems; i++)
786 {
787 reverse_memcpy(buffer, p, size);
788 p+= size;
789 write_buf (dtp, buffer, size);
790 }
791 }
792 }
793
794
795 /* Return a pointer to the name of a type. */
796
797 const char *
798 type_name (bt type)
799 {
800 const char *p;
801
802 switch (type)
803 {
804 case BT_INTEGER:
805 p = "INTEGER";
806 break;
807 case BT_LOGICAL:
808 p = "LOGICAL";
809 break;
810 case BT_CHARACTER:
811 p = "CHARACTER";
812 break;
813 case BT_REAL:
814 p = "REAL";
815 break;
816 case BT_COMPLEX:
817 p = "COMPLEX";
818 break;
819 default:
820 internal_error (NULL, "type_name(): Bad type");
821 }
822
823 return p;
824 }
825
826
827 /* Write a constant string to the output.
828 This is complicated because the string can have doubled delimiters
829 in it. The length in the format node is the true length. */
830
831 static void
832 write_constant_string (st_parameter_dt *dtp, const fnode *f)
833 {
834 char c, delimiter, *p, *q;
835 int length;
836
837 length = f->u.string.length;
838 if (length == 0)
839 return;
840
841 p = write_block (dtp, length);
842 if (p == NULL)
843 return;
844
845 q = f->u.string.p;
846 delimiter = q[-1];
847
848 for (; length > 0; length--)
849 {
850 c = *p++ = *q++;
851 if (c == delimiter && c != 'H' && c != 'h')
852 q++; /* Skip the doubled delimiter. */
853 }
854 }
855
856
857 /* Given actual and expected types in a formatted data transfer, make
858 sure they agree. If not, an error message is generated. Returns
859 nonzero if something went wrong. */
860
861 static int
862 require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
863 {
864 char buffer[100];
865
866 if (actual == expected)
867 return 0;
868
869 sprintf (buffer, "Expected %s for item %d in formatted transfer, got %s",
870 type_name (expected), dtp->u.p.item_count, type_name (actual));
871
872 format_error (dtp, f, buffer);
873 return 1;
874 }
875
876
877 /* This subroutine is the main loop for a formatted data transfer
878 statement. It would be natural to implement this as a coroutine
879 with the user program, but C makes that awkward. We loop,
880 processing format elements. When we actually have to transfer
881 data instead of just setting flags, we return control to the user
882 program which calls a subroutine that supplies the address and type
883 of the next element, then comes back here to process it. */
884
885 static void
886 formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
887 size_t size)
888 {
889 char scratch[SCRATCH_SIZE];
890 int pos, bytes_used;
891 const fnode *f;
892 format_token t;
893 int n;
894 int consume_data_flag;
895
896 /* Change a complex data item into a pair of reals. */
897
898 n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
899 if (type == BT_COMPLEX)
900 {
901 type = BT_REAL;
902 size /= 2;
903 }
904
905 /* If there's an EOR condition, we simulate finalizing the transfer
906 by doing nothing. */
907 if (dtp->u.p.eor_condition)
908 return;
909
910 /* Set this flag so that commas in reads cause the read to complete before
911 the entire field has been read. The next read field will start right after
912 the comma in the stream. (Set to 0 for character reads). */
913 dtp->u.p.sf_read_comma = 1;
914 dtp->u.p.line_buffer = scratch;
915
916 for (;;)
917 {
918 /* If reversion has occurred and there is another real data item,
919 then we have to move to the next record. */
920 if (dtp->u.p.reversion_flag && n > 0)
921 {
922 dtp->u.p.reversion_flag = 0;
923 next_record (dtp, 0);
924 }
925
926 consume_data_flag = 1 ;
927 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
928 break;
929
930 f = next_format (dtp);
931 if (f == NULL)
932 {
933 /* No data descriptors left. */
934 if (n > 0)
935 generate_error (&dtp->common, LIBERROR_FORMAT,
936 "Insufficient data descriptors in format after reversion");
937 return;
938 }
939
940 /* Now discharge T, TR and X movements to the right. This is delayed
941 until a data producing format to suppress trailing spaces. */
942
943 t = f->format;
944 if (dtp->u.p.mode == WRITING && dtp->u.p.skips != 0
945 && ((n>0 && ( t == FMT_I || t == FMT_B || t == FMT_O
946 || t == FMT_Z || t == FMT_F || t == FMT_E
947 || t == FMT_EN || t == FMT_ES || t == FMT_G
948 || t == FMT_L || t == FMT_A || t == FMT_D))
949 || t == FMT_STRING))
950 {
951 if (dtp->u.p.skips > 0)
952 {
953 int tmp;
954 write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
955 tmp = (int)(dtp->u.p.current_unit->recl
956 - dtp->u.p.current_unit->bytes_left);
957 dtp->u.p.max_pos =
958 dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
959 }
960 if (dtp->u.p.skips < 0)
961 {
962 move_pos_offset (dtp->u.p.current_unit->s, dtp->u.p.skips);
963 dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
964 }
965 dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
966 }
967
968 bytes_used = (int)(dtp->u.p.current_unit->recl
969 - dtp->u.p.current_unit->bytes_left);
970
971 if (is_stream_io(dtp))
972 bytes_used = 0;
973
974 switch (t)
975 {
976 case FMT_I:
977 if (n == 0)
978 goto need_data;
979 if (require_type (dtp, BT_INTEGER, type, f))
980 return;
981
982 if (dtp->u.p.mode == READING)
983 read_decimal (dtp, f, p, len);
984 else
985 write_i (dtp, f, p, len);
986
987 break;
988
989 case FMT_B:
990 if (n == 0)
991 goto need_data;
992
993 if (compile_options.allow_std < GFC_STD_GNU
994 && require_type (dtp, BT_INTEGER, type, f))
995 return;
996
997 if (dtp->u.p.mode == READING)
998 read_radix (dtp, f, p, len, 2);
999 else
1000 write_b (dtp, f, p, len);
1001
1002 break;
1003
1004 case FMT_O:
1005 if (n == 0)
1006 goto need_data;
1007
1008 if (compile_options.allow_std < GFC_STD_GNU
1009 && require_type (dtp, BT_INTEGER, type, f))
1010 return;
1011
1012 if (dtp->u.p.mode == READING)
1013 read_radix (dtp, f, p, len, 8);
1014 else
1015 write_o (dtp, f, p, len);
1016
1017 break;
1018
1019 case FMT_Z:
1020 if (n == 0)
1021 goto need_data;
1022
1023 if (compile_options.allow_std < GFC_STD_GNU
1024 && require_type (dtp, BT_INTEGER, type, f))
1025 return;
1026
1027 if (dtp->u.p.mode == READING)
1028 read_radix (dtp, f, p, len, 16);
1029 else
1030 write_z (dtp, f, p, len);
1031
1032 break;
1033
1034 case FMT_A:
1035 if (n == 0)
1036 goto need_data;
1037
1038 if (dtp->u.p.mode == READING)
1039 read_a (dtp, f, p, len);
1040 else
1041 write_a (dtp, f, p, len);
1042
1043 break;
1044
1045 case FMT_L:
1046 if (n == 0)
1047 goto need_data;
1048
1049 if (dtp->u.p.mode == READING)
1050 read_l (dtp, f, p, len);
1051 else
1052 write_l (dtp, f, p, len);
1053
1054 break;
1055
1056 case FMT_D:
1057 if (n == 0)
1058 goto need_data;
1059 if (require_type (dtp, BT_REAL, type, f))
1060 return;
1061
1062 if (dtp->u.p.mode == READING)
1063 read_f (dtp, f, p, len);
1064 else
1065 write_d (dtp, f, p, len);
1066
1067 break;
1068
1069 case FMT_E:
1070 if (n == 0)
1071 goto need_data;
1072 if (require_type (dtp, BT_REAL, type, f))
1073 return;
1074
1075 if (dtp->u.p.mode == READING)
1076 read_f (dtp, f, p, len);
1077 else
1078 write_e (dtp, f, p, len);
1079 break;
1080
1081 case FMT_EN:
1082 if (n == 0)
1083 goto need_data;
1084 if (require_type (dtp, BT_REAL, type, f))
1085 return;
1086
1087 if (dtp->u.p.mode == READING)
1088 read_f (dtp, f, p, len);
1089 else
1090 write_en (dtp, f, p, len);
1091
1092 break;
1093
1094 case FMT_ES:
1095 if (n == 0)
1096 goto need_data;
1097 if (require_type (dtp, BT_REAL, type, f))
1098 return;
1099
1100 if (dtp->u.p.mode == READING)
1101 read_f (dtp, f, p, len);
1102 else
1103 write_es (dtp, f, p, len);
1104
1105 break;
1106
1107 case FMT_F:
1108 if (n == 0)
1109 goto need_data;
1110 if (require_type (dtp, BT_REAL, type, f))
1111 return;
1112
1113 if (dtp->u.p.mode == READING)
1114 read_f (dtp, f, p, len);
1115 else
1116 write_f (dtp, f, p, len);
1117
1118 break;
1119
1120 case FMT_G:
1121 if (n == 0)
1122 goto need_data;
1123 if (dtp->u.p.mode == READING)
1124 switch (type)
1125 {
1126 case BT_INTEGER:
1127 read_decimal (dtp, f, p, len);
1128 break;
1129 case BT_LOGICAL:
1130 read_l (dtp, f, p, len);
1131 break;
1132 case BT_CHARACTER:
1133 read_a (dtp, f, p, len);
1134 break;
1135 case BT_REAL:
1136 read_f (dtp, f, p, len);
1137 break;
1138 default:
1139 goto bad_type;
1140 }
1141 else
1142 switch (type)
1143 {
1144 case BT_INTEGER:
1145 write_i (dtp, f, p, len);
1146 break;
1147 case BT_LOGICAL:
1148 write_l (dtp, f, p, len);
1149 break;
1150 case BT_CHARACTER:
1151 write_a (dtp, f, p, len);
1152 break;
1153 case BT_REAL:
1154 write_d (dtp, f, p, len);
1155 break;
1156 default:
1157 bad_type:
1158 internal_error (&dtp->common,
1159 "formatted_transfer(): Bad type");
1160 }
1161
1162 break;
1163
1164 case FMT_STRING:
1165 consume_data_flag = 0 ;
1166 if (dtp->u.p.mode == READING)
1167 {
1168 format_error (dtp, f, "Constant string in input format");
1169 return;
1170 }
1171 write_constant_string (dtp, f);
1172 break;
1173
1174 /* Format codes that don't transfer data. */
1175 case FMT_X:
1176 case FMT_TR:
1177 consume_data_flag = 0;
1178
1179 dtp->u.p.skips += f->u.n;
1180 pos = bytes_used + dtp->u.p.skips - 1;
1181 dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
1182
1183 /* Writes occur just before the switch on f->format, above, so
1184 that trailing blanks are suppressed, unless we are doing a
1185 non-advancing write in which case we want to output the blanks
1186 now. */
1187 if (dtp->u.p.mode == WRITING
1188 && dtp->u.p.advance_status == ADVANCE_NO)
1189 {
1190 write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
1191 dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1192 }
1193
1194 if (dtp->u.p.mode == READING)
1195 read_x (dtp, f->u.n);
1196
1197 break;
1198
1199 case FMT_TL:
1200 case FMT_T:
1201 consume_data_flag = 0;
1202
1203 if (f->format == FMT_TL)
1204 {
1205
1206 /* Handle the special case when no bytes have been used yet.
1207 Cannot go below zero. */
1208 if (bytes_used == 0)
1209 {
1210 dtp->u.p.pending_spaces -= f->u.n;
1211 dtp->u.p.skips -= f->u.n;
1212 dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
1213 }
1214
1215 pos = bytes_used - f->u.n;
1216 }
1217 else /* FMT_T */
1218 {
1219 if (dtp->u.p.mode == READING)
1220 pos = f->u.n - 1;
1221 else
1222 pos = f->u.n - dtp->u.p.pending_spaces - 1;
1223 }
1224
1225 /* Standard 10.6.1.1: excessive left tabbing is reset to the
1226 left tab limit. We do not check if the position has gone
1227 beyond the end of record because a subsequent tab could
1228 bring us back again. */
1229 pos = pos < 0 ? 0 : pos;
1230
1231 dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
1232 dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
1233 + pos - dtp->u.p.max_pos;
1234 dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
1235 ? 0 : dtp->u.p.pending_spaces;
1236
1237 if (dtp->u.p.skips == 0)
1238 break;
1239
1240 /* Writes occur just before the switch on f->format, above, so that
1241 trailing blanks are suppressed. */
1242 if (dtp->u.p.mode == READING)
1243 {
1244 /* Adjust everything for end-of-record condition */
1245 if (dtp->u.p.sf_seen_eor && !is_internal_unit (dtp))
1246 {
1247 if (dtp->u.p.sf_seen_eor == 2)
1248 {
1249 /* The EOR was a CRLF (two bytes wide). */
1250 dtp->u.p.current_unit->bytes_left -= 2;
1251 dtp->u.p.skips -= 2;
1252 }
1253 else
1254 {
1255 /* The EOR marker was only one byte wide. */
1256 dtp->u.p.current_unit->bytes_left--;
1257 dtp->u.p.skips--;
1258 }
1259 bytes_used = pos;
1260 dtp->u.p.sf_seen_eor = 0;
1261 }
1262 if (dtp->u.p.skips < 0)
1263 {
1264 move_pos_offset (dtp->u.p.current_unit->s, dtp->u.p.skips);
1265 dtp->u.p.current_unit->bytes_left
1266 -= (gfc_offset) dtp->u.p.skips;
1267 dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1268 }
1269 else
1270 read_x (dtp, dtp->u.p.skips);
1271 }
1272 else
1273 {
1274 if (dtp->u.p.skips < 0)
1275 flush (dtp->u.p.current_unit->s);
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 else
2011 dtp->rec = 0;
2012
2013 /* Overwriting an existing sequential file ?
2014 it is always safe to truncate the file on the first write */
2015 if (dtp->u.p.mode == WRITING
2016 && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL
2017 && dtp->u.p.current_unit->last_record == 0
2018 && !is_preconnected(dtp->u.p.current_unit->s))
2019 struncate(dtp->u.p.current_unit->s);
2020
2021 /* Bugware for badly written mixed C-Fortran I/O. */
2022 flush_if_preconnected(dtp->u.p.current_unit->s);
2023
2024 dtp->u.p.current_unit->mode = dtp->u.p.mode;
2025
2026 /* Set the initial value of flags. */
2027
2028 dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;
2029 dtp->u.p.sign_status = SIGN_S;
2030
2031 /* Set the maximum position reached from the previous I/O operation. This
2032 could be greater than zero from a previous non-advancing write. */
2033 dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
2034
2035 pre_position (dtp);
2036
2037 /* Set up the subroutine that will handle the transfers. */
2038
2039 if (read_flag)
2040 {
2041 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
2042 dtp->u.p.transfer = unformatted_read;
2043 else
2044 {
2045 if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
2046 dtp->u.p.transfer = list_formatted_read;
2047 else
2048 dtp->u.p.transfer = formatted_transfer;
2049 }
2050 }
2051 else
2052 {
2053 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
2054 dtp->u.p.transfer = unformatted_write;
2055 else
2056 {
2057 if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
2058 dtp->u.p.transfer = list_formatted_write;
2059 else
2060 dtp->u.p.transfer = formatted_transfer;
2061 }
2062 }
2063
2064 /* Make sure that we don't do a read after a nonadvancing write. */
2065
2066 if (read_flag)
2067 {
2068 if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
2069 {
2070 generate_error (&dtp->common, LIBERROR_BAD_OPTION,
2071 "Cannot READ after a nonadvancing WRITE");
2072 return;
2073 }
2074 }
2075 else
2076 {
2077 if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
2078 dtp->u.p.current_unit->read_bad = 1;
2079 }
2080
2081 /* Start the data transfer if we are doing a formatted transfer. */
2082 if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
2083 && ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0)
2084 && dtp->u.p.ionml == NULL)
2085 formatted_transfer (dtp, 0, NULL, 0, 0, 1);
2086 }
2087
2088 /* Initialize an array_loop_spec given the array descriptor. The function
2089 returns the index of the last element of the array, and also returns
2090 starting record, where the first I/O goes to (necessary in case of
2091 negative strides). */
2092
2093 gfc_offset
2094 init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
2095 gfc_offset *start_record)
2096 {
2097 int rank = GFC_DESCRIPTOR_RANK(desc);
2098 int i;
2099 gfc_offset index;
2100 int empty;
2101
2102 empty = 0;
2103 index = 1;
2104 *start_record = 0;
2105
2106 for (i=0; i<rank; i++)
2107 {
2108 ls[i].idx = desc->dim[i].lbound;
2109 ls[i].start = desc->dim[i].lbound;
2110 ls[i].end = desc->dim[i].ubound;
2111 ls[i].step = desc->dim[i].stride;
2112 empty = empty || (desc->dim[i].ubound < desc->dim[i].lbound);
2113
2114 if (desc->dim[i].stride > 0)
2115 {
2116 index += (desc->dim[i].ubound - desc->dim[i].lbound)
2117 * desc->dim[i].stride;
2118 }
2119 else
2120 {
2121 index -= (desc->dim[i].ubound - desc->dim[i].lbound)
2122 * desc->dim[i].stride;
2123 *start_record -= (desc->dim[i].ubound - desc->dim[i].lbound)
2124 * desc->dim[i].stride;
2125 }
2126 }
2127
2128 if (empty)
2129 return 0;
2130 else
2131 return index;
2132 }
2133
2134 /* Determine the index to the next record in an internal unit array by
2135 by incrementing through the array_loop_spec. */
2136
2137 gfc_offset
2138 next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
2139 {
2140 int i, carry;
2141 gfc_offset index;
2142
2143 carry = 1;
2144 index = 0;
2145
2146 for (i = 0; i < dtp->u.p.current_unit->rank; i++)
2147 {
2148 if (carry)
2149 {
2150 ls[i].idx++;
2151 if (ls[i].idx > ls[i].end)
2152 {
2153 ls[i].idx = ls[i].start;
2154 carry = 1;
2155 }
2156 else
2157 carry = 0;
2158 }
2159 index = index + (ls[i].idx - ls[i].start) * ls[i].step;
2160 }
2161
2162 *finished = carry;
2163
2164 return index;
2165 }
2166
2167
2168
2169 /* Skip to the end of the current record, taking care of an optional
2170 record marker of size bytes. If the file is not seekable, we
2171 read chunks of size MAX_READ until we get to the right
2172 position. */
2173
2174 #define MAX_READ 4096
2175
2176 static void
2177 skip_record (st_parameter_dt *dtp, size_t bytes)
2178 {
2179 gfc_offset new;
2180 int rlength, length;
2181 char *p;
2182
2183 dtp->u.p.current_unit->bytes_left_subrecord += bytes;
2184 if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
2185 return;
2186
2187 if (is_seekable (dtp->u.p.current_unit->s))
2188 {
2189 new = file_position (dtp->u.p.current_unit->s)
2190 + dtp->u.p.current_unit->bytes_left_subrecord;
2191
2192 /* Direct access files do not generate END conditions,
2193 only I/O errors. */
2194 if (sseek (dtp->u.p.current_unit->s, new) == FAILURE)
2195 generate_error (&dtp->common, LIBERROR_OS, NULL);
2196 }
2197 else
2198 { /* Seek by reading data. */
2199 while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
2200 {
2201 rlength = length =
2202 (MAX_READ > dtp->u.p.current_unit->bytes_left_subrecord) ?
2203 MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
2204
2205 p = salloc_r (dtp->u.p.current_unit->s, &rlength);
2206 if (p == NULL)
2207 {
2208 generate_error (&dtp->common, LIBERROR_OS, NULL);
2209 return;
2210 }
2211
2212 dtp->u.p.current_unit->bytes_left_subrecord -= length;
2213 }
2214 }
2215
2216 }
2217
2218 #undef MAX_READ
2219
2220 /* Advance to the next record reading unformatted files, taking
2221 care of subrecords. If complete_record is nonzero, we loop
2222 until all subrecords are cleared. */
2223
2224 static void
2225 next_record_r_unf (st_parameter_dt *dtp, int complete_record)
2226 {
2227 size_t bytes;
2228
2229 bytes = compile_options.record_marker == 0 ?
2230 sizeof (GFC_INTEGER_4) : compile_options.record_marker;
2231
2232 while(1)
2233 {
2234
2235 /* Skip over tail */
2236
2237 skip_record (dtp, bytes);
2238
2239 if ( ! (complete_record && dtp->u.p.current_unit->continued))
2240 return;
2241
2242 us_read (dtp, 1);
2243 }
2244 }
2245
2246 /* Space to the next record for read mode. */
2247
2248 static void
2249 next_record_r (st_parameter_dt *dtp)
2250 {
2251 gfc_offset record;
2252 int length, bytes_left;
2253 char *p;
2254
2255 switch (current_mode (dtp))
2256 {
2257 /* No records in unformatted STREAM I/O. */
2258 case UNFORMATTED_STREAM:
2259 return;
2260
2261 case UNFORMATTED_SEQUENTIAL:
2262 next_record_r_unf (dtp, 1);
2263 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2264 break;
2265
2266 case FORMATTED_DIRECT:
2267 case UNFORMATTED_DIRECT:
2268 skip_record (dtp, 0);
2269 break;
2270
2271 case FORMATTED_STREAM:
2272 case FORMATTED_SEQUENTIAL:
2273 length = 1;
2274 /* sf_read has already terminated input because of an '\n' */
2275 if (dtp->u.p.sf_seen_eor)
2276 {
2277 dtp->u.p.sf_seen_eor = 0;
2278 break;
2279 }
2280
2281 if (is_internal_unit (dtp))
2282 {
2283 if (is_array_io (dtp))
2284 {
2285 int finished;
2286
2287 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
2288 &finished);
2289
2290 /* Now seek to this record. */
2291 record = record * dtp->u.p.current_unit->recl;
2292 if (sseek (dtp->u.p.current_unit->s, record) == FAILURE)
2293 {
2294 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
2295 break;
2296 }
2297 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2298 }
2299 else
2300 {
2301 bytes_left = (int) dtp->u.p.current_unit->bytes_left;
2302 p = salloc_r (dtp->u.p.current_unit->s, &bytes_left);
2303 if (p != NULL)
2304 dtp->u.p.current_unit->bytes_left
2305 = dtp->u.p.current_unit->recl;
2306 }
2307 break;
2308 }
2309 else do
2310 {
2311 p = salloc_r (dtp->u.p.current_unit->s, &length);
2312
2313 if (p == NULL)
2314 {
2315 generate_error (&dtp->common, LIBERROR_OS, NULL);
2316 break;
2317 }
2318
2319 if (length == 0)
2320 {
2321 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2322 break;
2323 }
2324
2325 if (is_stream_io (dtp))
2326 dtp->u.p.current_unit->strm_pos++;
2327 }
2328 while (*p != '\n');
2329
2330 break;
2331 }
2332
2333 if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL
2334 && !dtp->u.p.namelist_mode
2335 && dtp->u.p.current_unit->endfile == NO_ENDFILE
2336 && (file_length (dtp->u.p.current_unit->s) ==
2337 file_position (dtp->u.p.current_unit->s)))
2338 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2339
2340 }
2341
2342
2343 /* Small utility function to write a record marker, taking care of
2344 byte swapping and of choosing the correct size. */
2345
2346 inline static int
2347 write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
2348 {
2349 size_t len;
2350 GFC_INTEGER_4 buf4;
2351 GFC_INTEGER_8 buf8;
2352 char p[sizeof (GFC_INTEGER_8)];
2353
2354 if (compile_options.record_marker == 0)
2355 len = sizeof (GFC_INTEGER_4);
2356 else
2357 len = compile_options.record_marker;
2358
2359 /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
2360 if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
2361 {
2362 switch (len)
2363 {
2364 case sizeof (GFC_INTEGER_4):
2365 buf4 = buf;
2366 return swrite (dtp->u.p.current_unit->s, &buf4, &len);
2367 break;
2368
2369 case sizeof (GFC_INTEGER_8):
2370 buf8 = buf;
2371 return swrite (dtp->u.p.current_unit->s, &buf8, &len);
2372 break;
2373
2374 default:
2375 runtime_error ("Illegal value for record marker");
2376 break;
2377 }
2378 }
2379 else
2380 {
2381 switch (len)
2382 {
2383 case sizeof (GFC_INTEGER_4):
2384 buf4 = buf;
2385 reverse_memcpy (p, &buf4, sizeof (GFC_INTEGER_4));
2386 return swrite (dtp->u.p.current_unit->s, p, &len);
2387 break;
2388
2389 case sizeof (GFC_INTEGER_8):
2390 buf8 = buf;
2391 reverse_memcpy (p, &buf8, sizeof (GFC_INTEGER_8));
2392 return swrite (dtp->u.p.current_unit->s, p, &len);
2393 break;
2394
2395 default:
2396 runtime_error ("Illegal value for record marker");
2397 break;
2398 }
2399 }
2400
2401 }
2402
2403 /* Position to the next (sub)record in write mode for
2404 unformatted sequential files. */
2405
2406 static void
2407 next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
2408 {
2409 gfc_offset c, m, m_write;
2410 size_t record_marker;
2411
2412 /* Bytes written. */
2413 m = dtp->u.p.current_unit->recl_subrecord
2414 - dtp->u.p.current_unit->bytes_left_subrecord;
2415 c = file_position (dtp->u.p.current_unit->s);
2416
2417 /* Write the length tail. If we finish a record containing
2418 subrecords, we write out the negative length. */
2419
2420 if (dtp->u.p.current_unit->continued)
2421 m_write = -m;
2422 else
2423 m_write = m;
2424
2425 if (write_us_marker (dtp, m_write) != 0)
2426 goto io_error;
2427
2428 if (compile_options.record_marker == 0)
2429 record_marker = sizeof (GFC_INTEGER_4);
2430 else
2431 record_marker = compile_options.record_marker;
2432
2433 /* Seek to the head and overwrite the bogus length with the real
2434 length. */
2435
2436 if (sseek (dtp->u.p.current_unit->s, c - m - record_marker)
2437 == FAILURE)
2438 goto io_error;
2439
2440 if (next_subrecord)
2441 m_write = -m;
2442 else
2443 m_write = m;
2444
2445 if (write_us_marker (dtp, m_write) != 0)
2446 goto io_error;
2447
2448 /* Seek past the end of the current record. */
2449
2450 if (sseek (dtp->u.p.current_unit->s, c + record_marker) == FAILURE)
2451 goto io_error;
2452
2453 return;
2454
2455 io_error:
2456 generate_error (&dtp->common, LIBERROR_OS, NULL);
2457 return;
2458
2459 }
2460
2461 /* Position to the next record in write mode. */
2462
2463 static void
2464 next_record_w (st_parameter_dt *dtp, int done)
2465 {
2466 gfc_offset m, record, max_pos;
2467 int length;
2468 char *p;
2469
2470 /* Zero counters for X- and T-editing. */
2471 max_pos = dtp->u.p.max_pos;
2472 dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2473
2474 switch (current_mode (dtp))
2475 {
2476 /* No records in unformatted STREAM I/O. */
2477 case UNFORMATTED_STREAM:
2478 return;
2479
2480 case FORMATTED_DIRECT:
2481 if (dtp->u.p.current_unit->bytes_left == 0)
2482 break;
2483
2484 if (sset (dtp->u.p.current_unit->s, ' ',
2485 dtp->u.p.current_unit->bytes_left) == FAILURE)
2486 goto io_error;
2487
2488 break;
2489
2490 case UNFORMATTED_DIRECT:
2491 if (dtp->u.p.current_unit->bytes_left > 0)
2492 {
2493 length = (int) dtp->u.p.current_unit->bytes_left;
2494 p = salloc_w (dtp->u.p.current_unit->s, &length);
2495 memset (p, 0, length);
2496 }
2497
2498 if (sfree (dtp->u.p.current_unit->s) == FAILURE)
2499 goto io_error;
2500 break;
2501
2502 case UNFORMATTED_SEQUENTIAL:
2503 next_record_w_unf (dtp, 0);
2504 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2505 break;
2506
2507 case FORMATTED_STREAM:
2508 case FORMATTED_SEQUENTIAL:
2509
2510 if (is_internal_unit (dtp))
2511 {
2512 if (is_array_io (dtp))
2513 {
2514 int finished;
2515
2516 length = (int) dtp->u.p.current_unit->bytes_left;
2517
2518 /* If the farthest position reached is greater than current
2519 position, adjust the position and set length to pad out
2520 whats left. Otherwise just pad whats left.
2521 (for character array unit) */
2522 m = dtp->u.p.current_unit->recl
2523 - dtp->u.p.current_unit->bytes_left;
2524 if (max_pos > m)
2525 {
2526 length = (int) (max_pos - m);
2527 p = salloc_w (dtp->u.p.current_unit->s, &length);
2528 length = (int) (dtp->u.p.current_unit->recl - max_pos);
2529 }
2530
2531 if (sset (dtp->u.p.current_unit->s, ' ', length) == FAILURE)
2532 {
2533 generate_error (&dtp->common, LIBERROR_END, NULL);
2534 return;
2535 }
2536
2537 /* Now that the current record has been padded out,
2538 determine where the next record in the array is. */
2539 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
2540 &finished);
2541 if (finished)
2542 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2543
2544 /* Now seek to this record */
2545 record = record * dtp->u.p.current_unit->recl;
2546
2547 if (sseek (dtp->u.p.current_unit->s, record) == FAILURE)
2548 {
2549 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
2550 return;
2551 }
2552
2553 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2554 }
2555 else
2556 {
2557 length = 1;
2558
2559 /* If this is the last call to next_record move to the farthest
2560 position reached and set length to pad out the remainder
2561 of the record. (for character scaler unit) */
2562 if (done)
2563 {
2564 m = dtp->u.p.current_unit->recl
2565 - dtp->u.p.current_unit->bytes_left;
2566 if (max_pos > m)
2567 {
2568 length = (int) (max_pos - m);
2569 p = salloc_w (dtp->u.p.current_unit->s, &length);
2570 length = (int) (dtp->u.p.current_unit->recl - max_pos);
2571 }
2572 else
2573 length = (int) dtp->u.p.current_unit->bytes_left;
2574 }
2575
2576 if (sset (dtp->u.p.current_unit->s, ' ', length) == FAILURE)
2577 {
2578 generate_error (&dtp->common, LIBERROR_END, NULL);
2579 return;
2580 }
2581 }
2582 }
2583 else
2584 {
2585 size_t len;
2586 const char crlf[] = "\r\n";
2587
2588 /* Move to the farthest position reached in preparation for
2589 completing the record. (for file unit) */
2590 m = dtp->u.p.current_unit->recl -
2591 dtp->u.p.current_unit->bytes_left;
2592 if (max_pos > m)
2593 {
2594 length = (int) (max_pos - m);
2595 sseek (dtp->u.p.current_unit->s,
2596 file_position (dtp->u.p.current_unit->s) + length);
2597 }
2598 #ifdef HAVE_CRLF
2599 len = 2;
2600 #else
2601 len = 1;
2602 #endif
2603 if (swrite (dtp->u.p.current_unit->s, &crlf[2-len], &len) != 0)
2604 goto io_error;
2605
2606 if (is_stream_io (dtp))
2607 {
2608 dtp->u.p.current_unit->strm_pos += len;
2609 if (dtp->u.p.current_unit->strm_pos
2610 < file_length (dtp->u.p.current_unit->s))
2611 struncate (dtp->u.p.current_unit->s);
2612 }
2613 }
2614
2615 break;
2616
2617 io_error:
2618 generate_error (&dtp->common, LIBERROR_OS, NULL);
2619 break;
2620 }
2621 }
2622
2623 /* Position to the next record, which means moving to the end of the
2624 current record. This can happen under several different
2625 conditions. If the done flag is not set, we get ready to process
2626 the next record. */
2627
2628 void
2629 next_record (st_parameter_dt *dtp, int done)
2630 {
2631 gfc_offset fp; /* File position. */
2632
2633 dtp->u.p.current_unit->read_bad = 0;
2634
2635 if (dtp->u.p.mode == READING)
2636 next_record_r (dtp);
2637 else
2638 next_record_w (dtp, done);
2639
2640 if (!is_stream_io (dtp))
2641 {
2642 /* Keep position up to date for INQUIRE */
2643 if (done)
2644 update_position (dtp->u.p.current_unit);
2645
2646 dtp->u.p.current_unit->current_record = 0;
2647 if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
2648 {
2649 fp = file_position (dtp->u.p.current_unit->s);
2650 /* Calculate next record, rounding up partial records. */
2651 dtp->u.p.current_unit->last_record =
2652 (fp + dtp->u.p.current_unit->recl - 1) /
2653 dtp->u.p.current_unit->recl;
2654 }
2655 else
2656 dtp->u.p.current_unit->last_record++;
2657 }
2658
2659 if (!done)
2660 pre_position (dtp);
2661 }
2662
2663
2664 /* Finalize the current data transfer. For a nonadvancing transfer,
2665 this means advancing to the next record. For internal units close the
2666 stream associated with the unit. */
2667
2668 static void
2669 finalize_transfer (st_parameter_dt *dtp)
2670 {
2671 jmp_buf eof_jump;
2672 GFC_INTEGER_4 cf = dtp->common.flags;
2673
2674 if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
2675 *dtp->size = (GFC_IO_INT) dtp->u.p.size_used;
2676
2677 if (dtp->u.p.eor_condition)
2678 {
2679 generate_error (&dtp->common, LIBERROR_EOR, NULL);
2680 return;
2681 }
2682
2683 if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2684 return;
2685
2686 if ((dtp->u.p.ionml != NULL)
2687 && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
2688 {
2689 if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
2690 namelist_read (dtp);
2691 else
2692 namelist_write (dtp);
2693 }
2694
2695 dtp->u.p.transfer = NULL;
2696 if (dtp->u.p.current_unit == NULL)
2697 return;
2698
2699 dtp->u.p.eof_jump = &eof_jump;
2700 if (setjmp (eof_jump))
2701 {
2702 generate_error (&dtp->common, LIBERROR_END, NULL);
2703 return;
2704 }
2705
2706 if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
2707 {
2708 finish_list_read (dtp);
2709 sfree (dtp->u.p.current_unit->s);
2710 return;
2711 }
2712
2713 if (dtp->u.p.mode == WRITING)
2714 dtp->u.p.current_unit->previous_nonadvancing_write
2715 = dtp->u.p.advance_status == ADVANCE_NO;
2716
2717 if (is_stream_io (dtp))
2718 {
2719 if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
2720 && dtp->u.p.advance_status != ADVANCE_NO)
2721 next_record (dtp, 1);
2722
2723 if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
2724 && file_position (dtp->u.p.current_unit->s) >= dtp->rec)
2725 {
2726 flush (dtp->u.p.current_unit->s);
2727 sfree (dtp->u.p.current_unit->s);
2728 }
2729 return;
2730 }
2731
2732 dtp->u.p.current_unit->current_record = 0;
2733
2734 if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
2735 {
2736 dtp->u.p.seen_dollar = 0;
2737 sfree (dtp->u.p.current_unit->s);
2738 return;
2739 }
2740
2741 /* For non-advancing I/O, save the current maximum position for use in the
2742 next I/O operation if needed. */
2743 if (dtp->u.p.advance_status == ADVANCE_NO)
2744 {
2745 int bytes_written = (int) (dtp->u.p.current_unit->recl
2746 - dtp->u.p.current_unit->bytes_left);
2747 dtp->u.p.current_unit->saved_pos =
2748 dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
2749 flush (dtp->u.p.current_unit->s);
2750 return;
2751 }
2752
2753 dtp->u.p.current_unit->saved_pos = 0;
2754
2755 next_record (dtp, 1);
2756 sfree (dtp->u.p.current_unit->s);
2757 }
2758
2759 /* Transfer function for IOLENGTH. It doesn't actually do any
2760 data transfer, it just updates the length counter. */
2761
2762 static void
2763 iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
2764 void *dest __attribute__ ((unused)),
2765 int kind __attribute__((unused)),
2766 size_t size, size_t nelems)
2767 {
2768 if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
2769 *dtp->iolength += (GFC_IO_INT) size * nelems;
2770 }
2771
2772
2773 /* Initialize the IOLENGTH data transfer. This function is in essence
2774 a very much simplified version of data_transfer_init(), because it
2775 doesn't have to deal with units at all. */
2776
2777 static void
2778 iolength_transfer_init (st_parameter_dt *dtp)
2779 {
2780 if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
2781 *dtp->iolength = 0;
2782
2783 memset (&dtp->u.p, 0, sizeof (dtp->u.p));
2784
2785 /* Set up the subroutine that will handle the transfers. */
2786
2787 dtp->u.p.transfer = iolength_transfer;
2788 }
2789
2790
2791 /* Library entry point for the IOLENGTH form of the INQUIRE
2792 statement. The IOLENGTH form requires no I/O to be performed, but
2793 it must still be a runtime library call so that we can determine
2794 the iolength for dynamic arrays and such. */
2795
2796 extern void st_iolength (st_parameter_dt *);
2797 export_proto(st_iolength);
2798
2799 void
2800 st_iolength (st_parameter_dt *dtp)
2801 {
2802 library_start (&dtp->common);
2803 iolength_transfer_init (dtp);
2804 }
2805
2806 extern void st_iolength_done (st_parameter_dt *);
2807 export_proto(st_iolength_done);
2808
2809 void
2810 st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
2811 {
2812 free_ionml (dtp);
2813 if (dtp->u.p.scratch != NULL)
2814 free_mem (dtp->u.p.scratch);
2815 library_end ();
2816 }
2817
2818
2819 /* The READ statement. */
2820
2821 extern void st_read (st_parameter_dt *);
2822 export_proto(st_read);
2823
2824 void
2825 st_read (st_parameter_dt *dtp)
2826 {
2827 library_start (&dtp->common);
2828
2829 data_transfer_init (dtp, 1);
2830
2831 /* Handle complications dealing with the endfile record. */
2832
2833 if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
2834 switch (dtp->u.p.current_unit->endfile)
2835 {
2836 case NO_ENDFILE:
2837 break;
2838
2839 case AT_ENDFILE:
2840 if (!is_internal_unit (dtp))
2841 {
2842 generate_error (&dtp->common, LIBERROR_END, NULL);
2843 dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
2844 dtp->u.p.current_unit->current_record = 0;
2845 }
2846 break;
2847
2848 case AFTER_ENDFILE:
2849 generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
2850 dtp->u.p.current_unit->current_record = 0;
2851 break;
2852 }
2853 }
2854
2855 extern void st_read_done (st_parameter_dt *);
2856 export_proto(st_read_done);
2857
2858 void
2859 st_read_done (st_parameter_dt *dtp)
2860 {
2861 finalize_transfer (dtp);
2862 free_format_data (dtp);
2863 free_ionml (dtp);
2864 if (dtp->u.p.scratch != NULL)
2865 free_mem (dtp->u.p.scratch);
2866 if (dtp->u.p.current_unit != NULL)
2867 unlock_unit (dtp->u.p.current_unit);
2868
2869 free_internal_unit (dtp);
2870
2871 library_end ();
2872 }
2873
2874 extern void st_write (st_parameter_dt *);
2875 export_proto(st_write);
2876
2877 void
2878 st_write (st_parameter_dt *dtp)
2879 {
2880 library_start (&dtp->common);
2881 data_transfer_init (dtp, 0);
2882 }
2883
2884 extern void st_write_done (st_parameter_dt *);
2885 export_proto(st_write_done);
2886
2887 void
2888 st_write_done (st_parameter_dt *dtp)
2889 {
2890 finalize_transfer (dtp);
2891
2892 /* Deal with endfile conditions associated with sequential files. */
2893
2894 if (dtp->u.p.current_unit != NULL
2895 && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
2896 switch (dtp->u.p.current_unit->endfile)
2897 {
2898 case AT_ENDFILE: /* Remain at the endfile record. */
2899 break;
2900
2901 case AFTER_ENDFILE:
2902 dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now. */
2903 break;
2904
2905 case NO_ENDFILE:
2906 /* Get rid of whatever is after this record. */
2907 if (!is_internal_unit (dtp))
2908 {
2909 flush (dtp->u.p.current_unit->s);
2910 if (struncate (dtp->u.p.current_unit->s) == FAILURE)
2911 generate_error (&dtp->common, LIBERROR_OS, NULL);
2912 }
2913 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2914 break;
2915 }
2916
2917 free_format_data (dtp);
2918 free_ionml (dtp);
2919 if (dtp->u.p.scratch != NULL)
2920 free_mem (dtp->u.p.scratch);
2921 if (dtp->u.p.current_unit != NULL)
2922 unlock_unit (dtp->u.p.current_unit);
2923
2924 free_internal_unit (dtp);
2925
2926 library_end ();
2927 }
2928
2929 /* Receives the scalar information for namelist objects and stores it
2930 in a linked list of namelist_info types. */
2931
2932 extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
2933 GFC_INTEGER_4, gfc_charlen_type, GFC_INTEGER_4);
2934 export_proto(st_set_nml_var);
2935
2936
2937 void
2938 st_set_nml_var (st_parameter_dt *dtp, void * var_addr, char * var_name,
2939 GFC_INTEGER_4 len, gfc_charlen_type string_length,
2940 GFC_INTEGER_4 dtype)
2941 {
2942 namelist_info *t1 = NULL;
2943 namelist_info *nml;
2944 size_t var_name_len = strlen (var_name);
2945
2946 nml = (namelist_info*) get_mem (sizeof (namelist_info));
2947
2948 nml->mem_pos = var_addr;
2949
2950 nml->var_name = (char*) get_mem (var_name_len + 1);
2951 memcpy (nml->var_name, var_name, var_name_len);
2952 nml->var_name[var_name_len] = '\0';
2953
2954 nml->len = (int) len;
2955 nml->string_length = (index_type) string_length;
2956
2957 nml->var_rank = (int) (dtype & GFC_DTYPE_RANK_MASK);
2958 nml->size = (index_type) (dtype >> GFC_DTYPE_SIZE_SHIFT);
2959 nml->type = (bt) ((dtype & GFC_DTYPE_TYPE_MASK) >> GFC_DTYPE_TYPE_SHIFT);
2960
2961 if (nml->var_rank > 0)
2962 {
2963 nml->dim = (descriptor_dimension*)
2964 get_mem (nml->var_rank * sizeof (descriptor_dimension));
2965 nml->ls = (array_loop_spec*)
2966 get_mem (nml->var_rank * sizeof (array_loop_spec));
2967 }
2968 else
2969 {
2970 nml->dim = NULL;
2971 nml->ls = NULL;
2972 }
2973
2974 nml->next = NULL;
2975
2976 if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
2977 {
2978 dtp->common.flags |= IOPARM_DT_IONML_SET;
2979 dtp->u.p.ionml = nml;
2980 }
2981 else
2982 {
2983 for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
2984 t1->next = nml;
2985 }
2986 }
2987
2988 /* Store the dimensional information for the namelist object. */
2989 extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
2990 index_type, index_type,
2991 index_type);
2992 export_proto(st_set_nml_var_dim);
2993
2994 void
2995 st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
2996 index_type stride, index_type lbound,
2997 index_type ubound)
2998 {
2999 namelist_info * nml;
3000 int n;
3001
3002 n = (int)n_dim;
3003
3004 for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);
3005
3006 nml->dim[n].stride = stride;
3007 nml->dim[n].lbound = lbound;
3008 nml->dim[n].ubound = ubound;
3009 }
3010
3011 /* Reverse memcpy - used for byte swapping. */
3012
3013 void reverse_memcpy (void *dest, const void *src, size_t n)
3014 {
3015 char *d, *s;
3016 size_t i;
3017
3018 d = (char *) dest;
3019 s = (char *) src + n - 1;
3020
3021 /* Write with ascending order - this is likely faster
3022 on modern architectures because of write combining. */
3023 for (i=0; i<n; i++)
3024 *(d++) = *(s--);
3025 }