Merge reload-branch up to revision 101000
[official-gcc.git] / libgfortran / io / read.c
blobfbd38f13becd3624722283d8df5e8fdd9e7a012d
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)
9 any later version.
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
18 executable.)
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. */
31 #include "config.h"
32 #include <string.h>
33 #include <errno.h>
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include "libgfortran.h"
38 #include "io.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. */
45 void
46 set_integer (void *dest, int64_t value, int length)
48 switch (length)
50 case 8:
51 *((int64_t *) dest) = value;
52 break;
53 case 4:
54 *((int32_t *) dest) = value;
55 break;
56 case 2:
57 *((int16_t *) dest) = value;
58 break;
59 case 1:
60 *((int8_t *) dest) = value;
61 break;
62 default:
63 internal_error ("Bad integer kind");
68 /* max_value()-- Given a length (kind), return the maximum signed or
69 * unsigned value */
71 uint64_t
72 max_value (int length, int signed_flag)
74 uint64_t value;
76 switch (length)
78 case 8:
79 value = signed_flag ? 0x7fffffffffffffff : 0xffffffffffffffff;
80 break;
81 case 4:
82 value = signed_flag ? 0x7fffffff : 0xffffffff;
83 break;
84 case 2:
85 value = signed_flag ? 0x7fff : 0xffff;
86 break;
87 case 1:
88 value = signed_flag ? 0x7f : 0xff;
89 break;
90 default:
91 internal_error ("Bad integer kind");
94 return value;
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
101 * infinities. */
104 convert_real (void *dest, const char *buffer, int length)
106 errno = 0;
108 switch (length)
110 case 4:
111 *((float *) dest) =
112 #if defined(HAVE_STRTOF)
113 strtof (buffer, NULL);
114 #else
115 (float) strtod (buffer, NULL);
116 #endif
117 break;
118 case 8:
119 *((double *) dest) = strtod (buffer, NULL);
120 break;
121 default:
122 internal_error ("Unsupported real kind during IO");
125 if (errno != 0)
127 generate_error (ERROR_READ_VALUE,
128 "Range error during floating point read");
129 return 1;
132 return 0;
136 /* read_l()-- Read a logical value */
138 void
139 read_l (fnode * f, char *dest, int length)
141 char *p;
142 int w;
144 w = f->u.w;
145 p = read_block (&w);
146 if (p == NULL)
147 return;
149 while (*p == ' ')
151 if (--w == 0)
152 goto bad;
153 p++;
156 if (*p == '.')
158 if (--w == 0)
159 goto bad;
160 p++;
163 switch (*p)
165 case 't':
166 case 'T':
167 set_integer (dest, 1, length);
168 break;
169 case 'f':
170 case 'F':
171 set_integer (dest, 0, length);
172 break;
173 default:
174 bad:
175 generate_error (ERROR_READ_VALUE, "Bad value on logical read");
176 break;
181 /* read_a()-- Read a character record. This one is pretty easy. */
183 void
184 read_a (fnode * f, char *p, int length)
186 char *source;
187 int w, m, n;
189 w = f->u.w;
190 if (w == -1) /* '(A)' edit descriptor */
191 w = length;
193 source = read_block (&w);
194 if (source == NULL)
195 return;
196 if (w > length)
197 source += (w - length);
199 m = (w > length) ? length : w;
200 memcpy (p, source, m);
202 n = length - w;
203 if (n > 0)
204 memset (p + m, ' ', n);
208 /* eat_leading_spaces()-- Given a character pointer and a width,
209 * ignore the leading spaces. */
211 static char *
212 eat_leading_spaces (int *width, char *p)
214 for (;;)
216 if (*width == 0 || *p != ' ')
217 break;
219 (*width)--;
220 p++;
223 return p;
227 static char
228 next_char (char **p, int *w)
230 char c, *q;
232 if (*w == 0)
233 return '\0';
235 q = *p;
236 c = *q++;
237 *p = q;
239 (*w)--;
241 if (c != ' ')
242 return c;
243 if (g.blank_status == BLANK_ZERO)
244 return '0';
246 /* At this point, the rest of the field has to be trailing blanks */
248 while (*w > 0)
250 if (*q++ != ' ')
251 return '?';
252 (*w)--;
255 *p = q;
256 return '\0';
260 /* read_decimal()-- Read a decimal integer value. The values here are
261 * signed values. */
263 void
264 read_decimal (fnode * f, char *dest, int length)
266 unsigned value, maxv, maxv_10;
267 int v, w, negative;
268 char c, *p;
270 w = f->u.w;
271 p = read_block (&w);
272 if (p == NULL)
273 return;
275 p = eat_leading_spaces (&w, p);
276 if (w == 0)
278 set_integer (dest, 0, length);
279 return;
282 maxv = max_value (length, 1);
283 maxv_10 = maxv / 10;
285 negative = 0;
286 value = 0;
288 switch (*p)
290 case '-':
291 negative = 1;
292 /* Fall through */
294 case '+':
295 p++;
296 if (--w == 0)
297 goto bad;
298 /* Fall through */
300 default:
301 break;
304 /* At this point we have a digit-string */
305 value = 0;
307 for (;;)
309 c = next_char (&p, &w);
310 if (c == '\0')
311 break;
313 if (c < '0' || c > '9')
314 goto bad;
316 if (value > maxv_10)
317 goto overflow;
319 c -= '0';
320 value = 10 * value;
322 if (value > maxv - c)
323 goto overflow;
324 value += c;
327 v = (signed int) value;
328 if (negative)
329 v = -v;
331 set_integer (dest, v, length);
332 return;
334 bad:
335 generate_error (ERROR_READ_VALUE, "Bad value during integer read");
336 return;
338 overflow:
339 generate_error (ERROR_READ_OVERFLOW,
340 "Value overflowed during integer read");
341 return;
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. */
350 void
351 read_radix (fnode * f, char *dest, int length, int radix)
353 unsigned value, maxv, maxv_r;
354 int v, w, negative;
355 char c, *p;
357 w = f->u.w;
358 p = read_block (&w);
359 if (p == NULL)
360 return;
362 p = eat_leading_spaces (&w, p);
363 if (w == 0)
365 set_integer (dest, 0, length);
366 return;
369 maxv = max_value (length, 0);
370 maxv_r = maxv / radix;
372 negative = 0;
373 value = 0;
375 switch (*p)
377 case '-':
378 negative = 1;
379 /* Fall through */
381 case '+':
382 p++;
383 if (--w == 0)
384 goto bad;
385 /* Fall through */
387 default:
388 break;
391 /* At this point we have a digit-string */
392 value = 0;
394 for (;;)
396 c = next_char (&p, &w);
397 if (c == '\0')
398 break;
400 switch (radix)
402 case 2:
403 if (c < '0' || c > '1')
404 goto bad;
405 break;
407 case 8:
408 if (c < '0' || c > '7')
409 goto bad;
410 break;
412 case 16:
413 switch (c)
415 case '0':
416 case '1':
417 case '2':
418 case '3':
419 case '4':
420 case '5':
421 case '6':
422 case '7':
423 case '8':
424 case '9':
425 break;
427 case 'a':
428 case 'b':
429 case 'c':
430 case 'd':
431 case 'e':
432 case 'f':
433 c = c - 'a' + '9' + 1;
434 break;
436 case 'A':
437 case 'B':
438 case 'C':
439 case 'D':
440 case 'E':
441 case 'F':
442 c = c - 'A' + '9' + 1;
443 break;
445 default:
446 goto bad;
449 break;
452 if (value > maxv_r)
453 goto overflow;
455 c -= '0';
456 value = radix * value;
458 if (maxv - c < value)
459 goto overflow;
460 value += c;
463 v = (signed int) value;
464 if (negative)
465 v = -v;
467 set_integer (dest, v, length);
468 return;
470 bad:
471 generate_error (ERROR_READ_VALUE, "Bad value during integer read");
472 return;
474 overflow:
475 generate_error (ERROR_READ_OVERFLOW,
476 "Value overflowed during integer read");
477 return;
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
485 the input. */
487 void
488 read_f (fnode * f, char *dest, int length)
490 int w, seen_dp, exponent;
491 int exponent_sign, val_sign;
492 int ndigits;
493 int edigits;
494 int i;
495 char *p, *buffer;
496 char *digits;
498 val_sign = 1;
499 seen_dp = 0;
500 w = f->u.w;
501 p = read_block (&w);
502 if (p == NULL)
503 return;
505 p = eat_leading_spaces (&w, p);
506 if (w == 0)
507 goto zero;
509 /* Optional sign */
511 if (*p == '-' || *p == '+')
513 if (*p == '-')
514 val_sign = -1;
515 p++;
516 w--;
519 exponent_sign = 1;
520 p = eat_leading_spaces (&w, p);
521 if (w == 0)
522 goto zero;
524 /* A digit, a '.' or a exponent character ('e', 'E', 'd' or 'D')
525 is required at this point */
527 if (!isdigit (*p) && *p != '.' && *p != 'd' && *p != 'D'
528 && *p != 'e' && *p != 'E')
529 goto bad_float;
531 /* Remember the position of the first digit. */
532 digits = p;
533 ndigits = 0;
535 /* Scan through the string to find the exponent. */
536 while (w > 0)
538 switch (*p)
540 case '.':
541 if (seen_dp)
542 goto bad_float;
543 seen_dp = 1;
544 /* Fall through */
546 case '0':
547 case '1':
548 case '2':
549 case '3':
550 case '4':
551 case '5':
552 case '6':
553 case '7':
554 case '8':
555 case '9':
556 case ' ':
557 ndigits++;
558 *p++;
559 w--;
560 break;
562 case '-':
563 exponent_sign = -1;
564 /* Fall through */
566 case '+':
567 p++;
568 w--;
569 goto exp2;
571 case 'd':
572 case 'e':
573 case 'D':
574 case 'E':
575 p++;
576 w--;
577 goto exp1;
579 default:
580 goto bad_float;
584 /* No exponent has been seen, so we use the current scale factor */
585 exponent = -g.scale_factor;
586 goto done;
588 bad_float:
589 generate_error (ERROR_READ_VALUE, "Bad value during floating point read");
590 return;
592 /* The value read is zero */
593 zero:
594 switch (length)
596 case 4:
597 *((float *) dest) = 0.0f;
598 break;
600 case 8:
601 *((double *) dest) = 0.0;
602 break;
604 default:
605 internal_error ("Unsupported real kind during IO");
607 return;
609 /* At this point the start of an exponent has been found */
610 exp1:
611 while (w > 0 && *p == ' ')
613 w--;
614 p++;
617 switch (*p)
619 case '-':
620 exponent_sign = -1;
621 /* Fall through */
623 case '+':
624 p++;
625 w--;
626 break;
629 if (w == 0)
630 goto bad_float;
632 /* At this point a digit string is required. We calculate the value
633 of the exponent in order to take account of the scale factor and
634 the d parameter before explict conversion takes place. */
635 exp2:
636 if (!isdigit (*p))
637 goto bad_float;
639 exponent = *p - '0';
640 p++;
641 w--;
643 while (w > 0 && isdigit (*p))
645 exponent = 10 * exponent + *p - '0';
646 p++;
647 w--;
650 /* Only allow trailing blanks */
652 while (w > 0)
654 if (*p != ' ')
655 goto bad_float;
656 p++;
657 w--;
660 exponent = exponent * exponent_sign;
662 done:
663 /* Use the precision specified in the format if no decimal point has been
664 seen. */
665 if (!seen_dp)
666 exponent -= f->u.real.d;
668 if (exponent > 0)
670 edigits = 2;
671 i = exponent;
673 else
675 edigits = 3;
676 i = -exponent;
679 while (i >= 10)
681 i /= 10;
682 edigits++;
685 i = ndigits + edigits + 1;
686 if (val_sign < 0)
687 i++;
689 if (i < SCRATCH_SIZE)
690 buffer = scratch;
691 else
692 buffer = get_mem (i);
694 /* Reformat the string into a temporary buffer. As we're using atof it's
695 easiest to just leave the dcimal point in place. */
696 p = buffer;
697 if (val_sign < 0)
698 *(p++) = '-';
699 for (; ndigits > 0; ndigits--)
701 if (*digits == ' ' && g.blank_status == BLANK_ZERO)
702 *p = '0';
703 else
704 *p = *digits;
705 p++;
706 digits++;
708 *(p++) = 'e';
709 sprintf (p, "%d", exponent);
711 /* Do the actual conversion. */
712 convert_real (dest, buffer, length);
714 if (buffer != scratch)
715 free_mem (buffer);
717 return;
721 /* read_x()-- Deal with the X/TR descriptor. We just read some data
722 * and never look at it. */
724 void
725 read_x (fnode * f)
727 int n;
729 n = f->u.n;
730 read_block (&n);