OSDN Git Service

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