OSDN Git Service

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