OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libgfortran/] [io/] [transfer.c] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.