1 /* Copyright (C) 2002-2003 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
20 Libgfortran is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with Libgfortran; see the file COPYING. If not, write to
27 the Free Software Foundation, 59 Temple Place - Suite 330,
28 Boston, MA 02111-1307, USA. */
37 #include "libgfortran.h"
40 /* read.c -- Deal with formatted reads */
42 /* set_integer()-- All of the integer assignments come here to
43 * actually place the value into memory. */
46 set_integer (void *dest
, int64_t value
, int length
)
51 *((int64_t *) dest
) = value
;
54 *((int32_t *) dest
) = value
;
57 *((int16_t *) dest
) = value
;
60 *((int8_t *) dest
) = value
;
63 internal_error ("Bad integer kind");
68 /* max_value()-- Given a length (kind), return the maximum signed or
72 max_value (int length
, int signed_flag
)
79 value
= signed_flag
? 0x7fffffffffffffff : 0xffffffffffffffff;
82 value
= signed_flag
? 0x7fffffff : 0xffffffff;
85 value
= signed_flag
? 0x7fff : 0xffff;
88 value
= signed_flag
? 0x7f : 0xff;
91 internal_error ("Bad integer kind");
98 /* convert_real()-- Convert a character representation of a floating
99 * point number to the machine number. Returns nonzero if there is a
100 * range problem during conversion. TODO: handle not-a-numbers and
104 convert_real (void *dest
, const char *buffer
, int length
)
112 #if defined(HAVE_STRTOF)
113 strtof (buffer
, NULL
);
115 (float) strtod (buffer
, NULL
);
119 *((double *) dest
) = strtod (buffer
, NULL
);
122 internal_error ("Unsupported real kind during IO");
127 generate_error (ERROR_READ_VALUE
,
128 "Range error during floating point read");
136 /* read_l()-- Read a logical value */
139 read_l (fnode
* f
, char *dest
, int length
)
167 set_integer (dest
, 1, length
);
171 set_integer (dest
, 0, length
);
175 generate_error (ERROR_READ_VALUE
, "Bad value on logical read");
181 /* read_a()-- Read a character record. This one is pretty easy. */
184 read_a (fnode
* f
, char *p
, int length
)
190 if (w
== -1) /* '(A)' edit descriptor */
193 source
= read_block (&w
);
197 source
+= (w
- length
);
199 m
= (w
> length
) ? length
: w
;
200 memcpy (p
, source
, m
);
204 memset (p
+ m
, ' ', n
);
208 /* eat_leading_spaces()-- Given a character pointer and a width,
209 * ignore the leading spaces. */
212 eat_leading_spaces (int *width
, char *p
)
216 if (*width
== 0 || *p
!= ' ')
228 next_char (char **p
, int *w
)
243 if (g
.blank_status
== BLANK_ZERO
)
246 /* At this point, the rest of the field has to be trailing blanks */
260 /* read_decimal()-- Read a decimal integer value. The values here are
264 read_decimal (fnode
* f
, char *dest
, int length
)
266 unsigned value
, maxv
, maxv_10
;
275 p
= eat_leading_spaces (&w
, p
);
278 set_integer (dest
, 0, length
);
282 maxv
= max_value (length
, 1);
304 /* At this point we have a digit-string */
309 c
= next_char (&p
, &w
);
313 if (c
< '0' || c
> '9')
322 if (value
> maxv
- c
)
327 v
= (signed int) value
;
331 set_integer (dest
, v
, length
);
335 generate_error (ERROR_READ_VALUE
, "Bad value during integer read");
339 generate_error (ERROR_READ_OVERFLOW
,
340 "Value overflowed during integer read");
345 /* read_radix()-- This function reads values for non-decimal radixes.
346 * The difference here is that we treat the values here as unsigned
347 * values for the purposes of overflow. If minus sign is present and
348 * the top bit is set, the value will be incorrect. */
351 read_radix (fnode
* f
, char *dest
, int length
, int radix
)
353 unsigned value
, maxv
, maxv_r
;
362 p
= eat_leading_spaces (&w
, p
);
365 set_integer (dest
, 0, length
);
369 maxv
= max_value (length
, 0);
370 maxv_r
= maxv
/ radix
;
391 /* At this point we have a digit-string */
396 c
= next_char (&p
, &w
);
403 if (c
< '0' || c
> '1')
408 if (c
< '0' || c
> '7')
433 c
= c
- 'a' + '9' + 1;
442 c
= c
- 'A' + '9' + 1;
456 value
= radix
* value
;
458 if (maxv
- c
< value
)
463 v
= (signed int) value
;
467 set_integer (dest
, v
, length
);
471 generate_error (ERROR_READ_VALUE
, "Bad value during integer read");
475 generate_error (ERROR_READ_OVERFLOW
,
476 "Value overflowed during integer read");
481 /* read_f()-- Read a floating point number with F-style editing, which
482 is what all of the other floating point descriptors behave as. The
483 tricky part is that optional spaces are allowed after an E or D,
484 and the implicit decimal point if a decimal point is not present in
488 read_f (fnode
* f
, char *dest
, int length
)
490 int w
, seen_dp
, exponent
;
491 int exponent_sign
, val_sign
;
505 p
= eat_leading_spaces (&w
, p
);
511 *((float *) dest
) = 0.0f
;
515 *((double *) dest
) = 0.0;
519 internal_error ("Unsupported real kind during IO");
527 if (*p
== '-' || *p
== '+')
539 /* A digit (or a '.') is required at this point */
541 if (!isdigit (*p
) && *p
!= '.')
544 /* Remember the position of the first digit. */
548 /* Scan through the string to find the exponent. */
597 /* No exponent has been seen, so we use the current scale factor */
598 exponent
= -g
.scale_factor
;
602 generate_error (ERROR_READ_VALUE
, "Bad value during floating point read");
605 /* At this point the start of an exponent has been found */
607 while (w
> 0 && *p
== ' ')
628 /* At this point a digit string is required. We calculate the value
629 of the exponent in order to take account of the scale factor and
630 the d parameter before explict conversion takes place. */
639 while (w
> 0 && isdigit (*p
))
641 exponent
= 10 * exponent
+ *p
- '0';
646 /* Only allow trailing blanks */
656 exponent
= exponent
* exponent_sign
;
659 /* Use the precision specified in the format if no decimal point has been
662 exponent
-= f
->u
.real
.d
;
681 i
= ndigits
+ edigits
+ 1;
685 if (i
< SCRATCH_SIZE
)
688 buffer
= get_mem (i
);
690 /* Reformat the string into a temporary buffer. As we're using atof it's
691 easiest to just leave the dcimal point in place. */
695 for (; ndigits
> 0; ndigits
--)
697 if (*digits
== ' ' && g
.blank_status
== BLANK_ZERO
)
705 sprintf (p
, "%d", exponent
);
707 /* Do the actual conversion. */
708 convert_real (dest
, buffer
, length
);
710 if (buffer
!= scratch
)
717 /* read_x()-- Deal with the X/TR descriptor. We just read some data
718 * and never look at it. */