OSDN Git Service

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