PR fortran/18218
[official-gcc.git] / libgfortran / io / read.c
blob6999158c13ac5a02466d6f8dfdd85caf1b8467be
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 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Libgfortran; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include <string.h>
24 #include <errno.h>
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include "libgfortran.h"
29 #include "io.h"
31 /* read.c -- Deal with formatted reads */
33 /* set_integer()-- All of the integer assignments come here to
34 * actually place the value into memory. */
36 void
37 set_integer (void *dest, int64_t value, int length)
40 switch (length)
42 case 8:
43 *((int64_t *) dest) = value;
44 break;
45 case 4:
46 *((int32_t *) dest) = value;
47 break;
48 case 2:
49 *((int16_t *) dest) = value;
50 break;
51 case 1:
52 *((int8_t *) dest) = value;
53 break;
54 default:
55 internal_error ("Bad integer kind");
60 /* max_value()-- Given a length (kind), return the maximum signed or
61 * unsigned value */
63 uint64_t
64 max_value (int length, int signed_flag)
66 uint64_t value;
68 switch (length)
70 case 8:
71 value = signed_flag ? 0x7fffffffffffffff : 0xffffffffffffffff;
72 break;
73 case 4:
74 value = signed_flag ? 0x7fffffff : 0xffffffff;
75 break;
76 case 2:
77 value = signed_flag ? 0x7fff : 0xffff;
78 break;
79 case 1:
80 value = signed_flag ? 0x7f : 0xff;
81 break;
82 default:
83 internal_error ("Bad integer kind");
86 return value;
90 /* convert_real()-- Convert a character representation of a floating
91 * point number to the machine number. Returns nonzero if there is a
92 * range problem during conversion. TODO: handle not-a-numbers and
93 * infinities. */
95 int
96 convert_real (void *dest, const char *buffer, int length)
99 errno = 0;
101 switch (length)
103 case 4:
104 *((float *) dest) =
105 #if defined(HAVE_STRTOF)
106 strtof (buffer, NULL);
107 #else
108 (float) strtod (buffer, NULL);
109 #endif
110 break;
111 case 8:
112 *((double *) dest) = strtod (buffer, NULL);
113 break;
114 default:
115 internal_error ("Unsupported real kind during IO");
118 if (errno != 0)
120 generate_error (ERROR_READ_VALUE,
121 "Range error during floating point read");
122 return 1;
125 return 0;
129 /* read_l()-- Read a logical value */
131 void
132 read_l (fnode * f, char *dest, int length)
134 char *p;
135 int w;
137 w = f->u.w;
138 p = read_block (&w);
139 if (p == NULL)
140 return;
142 while (*p == ' ')
144 if (--w == 0)
145 goto bad;
146 p++;
149 if (*p == '.')
151 if (--w == 0)
152 goto bad;
153 p++;
156 switch (*p)
158 case 't':
159 case 'T':
160 set_integer (dest, 1, length);
161 break;
162 case 'f':
163 case 'F':
164 set_integer (dest, 0, length);
165 break;
166 default:
167 bad:
168 generate_error (ERROR_READ_VALUE, "Bad value on logical read");
169 break;
174 /* read_a()-- Read a character record. This one is pretty easy. */
176 void
177 read_a (fnode * f, char *p, int length)
179 char *source;
180 int w, m, n;
182 w = f->u.w;
183 if (w == -1) /* '(A)' edit descriptor */
184 w = length;
186 source = read_block (&w);
187 if (source == NULL)
188 return;
189 if (w > length)
190 source += (w - length);
192 m = (w > length) ? length : w;
193 memcpy (p, source, m);
195 n = length - w;
196 if (n > 0)
197 memset (p + m, ' ', n);
201 /* eat_leading_spaces()-- Given a character pointer and a width,
202 * ignore the leading spaces. */
204 static char *
205 eat_leading_spaces (int *width, char *p)
208 for (;;)
210 if (*width == 0 || *p != ' ')
211 break;
213 (*width)--;
214 p++;
217 return p;
221 static char
222 next_char (char **p, int *w)
224 char c, *q;
226 if (*w == 0)
227 return '\0';
229 q = *p;
230 c = *q++;
231 *p = q;
233 (*w)--;
235 if (c != ' ')
236 return c;
237 if (g.blank_status == BLANK_ZERO)
238 return '0';
240 /* At this point, the rest of the field has to be trailing blanks */
242 while (*w > 0)
244 if (*q++ != ' ')
245 return '?';
246 (*w)--;
249 *p = q;
250 return '\0';
254 /* read_decimal()-- Read a decimal integer value. The values here are
255 * signed values. */
257 void
258 read_decimal (fnode * f, char *dest, int length)
260 unsigned value, maxv, maxv_10;
261 int v, w, negative;
262 char c, *p;
264 w = f->u.w;
265 p = read_block (&w);
266 if (p == NULL)
267 return;
269 p = eat_leading_spaces (&w, p);
270 if (w == 0)
272 set_integer (dest, 0, length);
273 return;
276 maxv = max_value (length, 1);
277 maxv_10 = maxv / 10;
279 negative = 0;
280 value = 0;
282 switch (*p)
284 case '-':
285 negative = 1;
286 /* Fall through */
288 case '+':
289 p++;
290 if (--w == 0)
291 goto bad;
292 /* Fall through */
294 default:
295 break;
298 /* At this point we have a digit-string */
299 value = 0;
301 for (;;)
303 c = next_char (&p, &w);
304 if (c == '\0')
305 break;
307 if (c < '0' || c > '9')
308 goto bad;
310 if (value > maxv_10)
311 goto overflow;
313 c -= '0';
314 value = 10 * value;
316 if (value > maxv - c)
317 goto overflow;
318 value += c;
321 v = (signed int) value;
322 if (negative)
323 v = -v;
325 set_integer (dest, v, length);
326 return;
328 bad:
329 generate_error (ERROR_READ_VALUE, "Bad value during integer read");
330 return;
332 overflow:
333 generate_error (ERROR_READ_OVERFLOW,
334 "Value overflowed during integer read");
335 return;
339 /* read_radix()-- This function reads values for non-decimal radixes.
340 * The difference here is that we treat the values here as unsigned
341 * values for the purposes of overflow. If minus sign is present and
342 * the top bit is set, the value will be incorrect. */
344 void
345 read_radix (fnode * f, char *dest, int length, int radix)
347 unsigned value, maxv, maxv_r;
348 int v, w, negative;
349 char c, *p;
351 w = f->u.w;
352 p = read_block (&w);
353 if (p == NULL)
354 return;
356 p = eat_leading_spaces (&w, p);
357 if (w == 0)
359 set_integer (dest, 0, length);
360 return;
363 maxv = max_value (length, 0);
364 maxv_r = maxv / radix;
366 negative = 0;
367 value = 0;
369 switch (*p)
371 case '-':
372 negative = 1;
373 /* Fall through */
375 case '+':
376 p++;
377 if (--w == 0)
378 goto bad;
379 /* Fall through */
381 default:
382 break;
385 /* At this point we have a digit-string */
386 value = 0;
388 for (;;)
390 c = next_char (&p, &w);
391 if (c == '\0')
392 break;
394 switch (radix)
396 case 2:
397 if (c < '0' || c > '1')
398 goto bad;
399 break;
401 case 8:
402 if (c < '0' || c > '7')
403 goto bad;
404 break;
406 case 16:
407 switch (c)
409 case '0':
410 case '1':
411 case '2':
412 case '3':
413 case '4':
414 case '5':
415 case '6':
416 case '7':
417 case '8':
418 case '9':
419 break;
421 case 'a':
422 case 'b':
423 case 'c':
424 case 'd':
425 case 'e':
426 case 'f':
427 c = c - 'a' + '9' + 1;
428 break;
430 case 'A':
431 case 'B':
432 case 'C':
433 case 'D':
434 case 'E':
435 case 'F':
436 c = c - 'A' + '9' + 1;
437 break;
439 default:
440 goto bad;
443 break;
446 if (value > maxv_r)
447 goto overflow;
449 c -= '0';
450 value = radix * value;
452 if (maxv - c < value)
453 goto overflow;
454 value += c;
457 v = (signed int) value;
458 if (negative)
459 v = -v;
461 set_integer (dest, v, length);
462 return;
464 bad:
465 generate_error (ERROR_READ_VALUE, "Bad value during integer read");
466 return;
468 overflow:
469 generate_error (ERROR_READ_OVERFLOW,
470 "Value overflowed during integer read");
471 return;
475 /* read_f()-- Read a floating point number with F-style editing, which
476 is what all of the other floating point descriptors behave as. The
477 tricky part is that optional spaces are allowed after an E or D,
478 and the implicit decimal point if a decimal point is not present in
479 the input. */
481 void
482 read_f (fnode * f, char *dest, int length)
484 int w, seen_dp, exponent;
485 int exponent_sign, val_sign;
486 int ndigits;
487 int edigits;
488 int i;
489 char *p, *buffer;
490 char *digits;
492 val_sign = 1;
493 seen_dp = 0;
494 w = f->u.w;
495 p = read_block (&w);
496 if (p == NULL)
497 return;
499 p = eat_leading_spaces (&w, p);
500 if (w == 0)
502 switch (length)
504 case 4:
505 *((float *) dest) = 0.0f;
506 break;
508 case 8:
509 *((double *) dest) = 0.0;
510 break;
512 default:
513 internal_error ("Unsupported real kind during IO");
516 return;
519 /* Optional sign */
521 if (*p == '-' || *p == '+')
523 if (*p == '-')
524 val_sign = -1;
525 p++;
527 if (--w == 0)
528 goto bad_float;
531 exponent_sign = 1;
533 /* A digit (or a '.') is required at this point */
535 if (!isdigit (*p) && *p != '.')
536 goto bad_float;
538 /* Remember the position of the first digit. */
539 digits = p;
540 ndigits = 0;
542 /* Scan through the string to find the exponent. */
543 while (w > 0)
545 switch (*p)
547 case '.':
548 if (seen_dp)
549 goto bad_float;
550 seen_dp = 1;
551 /* Fall through */
553 case '0':
554 case '1':
555 case '2':
556 case '3':
557 case '4':
558 case '5':
559 case '6':
560 case '7':
561 case '8':
562 case '9':
563 case ' ':
564 ndigits++;
565 *p++;
566 w--;
567 break;
569 case '-':
570 exponent_sign = -1;
571 /* Fall through */
573 case '+':
574 p++;
575 w--;
576 goto exp2;
578 case 'd':
579 case 'e':
580 case 'D':
581 case 'E':
582 p++;
583 w--;
584 goto exp1;
586 default:
587 goto bad_float;
591 /* No exponent has been seen, so we use the current scale factor */
593 exponent = -g.scale_factor;
594 goto done;
596 bad_float:
597 generate_error (ERROR_READ_VALUE, "Bad value during floating point read");
598 if (buffer != scratch)
599 free_mem (buffer);
600 return;
602 /* At this point the start of an exponent has been found */
604 exp1:
605 while (w > 0 && *p == ' ')
607 w--;
608 p++;
611 switch (*p)
613 case '-':
614 exponent_sign = -1;
615 /* Fall through */
617 case '+':
618 p++;
619 w--;
620 break;
623 if (w == 0)
624 goto bad_float;
626 /* At this point a digit string is required. We calculate the value
627 of the exponent in order to take account of the scale factor and
628 the d parameter before explict conversion takes place. */
630 exp2:
631 if (!isdigit (*p))
632 goto bad_float;
634 exponent = *p - '0';
635 p++;
636 w--;
638 while (w > 0 && isdigit (*p))
640 exponent = 10 * exponent + *p - '0';
641 p++;
642 w--;
645 /* Only allow trailing blanks */
647 while (w > 0)
649 if (*p != ' ')
650 goto bad_float;
651 p++;
652 w--;
655 exponent = exponent * exponent_sign;
657 done:
658 /* Use the precision specified in the format if no decimal point has been
659 seen. */
660 if (!seen_dp)
661 exponent -= f->u.real.d;
663 if (exponent > 0)
665 edigits = 2;
666 i = exponent;
668 else
670 edigits = 3;
671 i = -exponent;
674 while (i >= 10)
676 i /= 10;
677 edigits++;
680 i = ndigits + edigits + 1;
681 if (val_sign < 0)
682 i++;
684 if (i < SCRATCH_SIZE)
685 buffer = scratch;
686 else
687 buffer = get_mem (i);
689 /* Reformat the string into a temporary buffer. As we're using atof it's
690 easiest to just leave the dcimal point in place. */
691 p = buffer;
692 if (val_sign < 0)
693 *(p++) = '-';
694 for (; ndigits > 0; ndigits--)
696 if (*digits == ' ' && g.blank_status == BLANK_ZERO)
697 *p = '0';
698 else
699 *p = *digits;
700 p++;
701 digits++;
703 *(p++) = 'e';
704 sprintf (p, "%d", exponent);
706 /* Do the actual conversion. */
707 string_to_real (dest, buffer, length);
709 if (buffer != scratch)
710 free_mem (buffer);
712 return;
716 /* read_x()-- Deal with the X/TR descriptor. We just read some data
717 * and never look at it. */
719 void
720 read_x (fnode * f)
722 int n;
724 n = f->u.n;
725 read_block (&n);