WARNS=6 safeness:
[dragonfly.git] / contrib / binutils-2.14 / gas / atof-generic.c
1 /* atof_generic.c - turn a string of digits into a Flonum
2    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4
5    This file is part of GAS, the GNU Assembler.
6
7    GAS 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    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #include <string.h>
23
24 #include "as.h"
25 #include "safe-ctype.h"
26
27 #ifndef FALSE
28 #define FALSE (0)
29 #endif
30 #ifndef TRUE
31 #define TRUE  (1)
32 #endif
33
34 #ifdef TRACE
35 static void flonum_print PARAMS ((const FLONUM_TYPE *));
36 #endif
37
38 #define ASSUME_DECIMAL_MARK_IS_DOT
39
40 /***********************************************************************\
41  *                                                                      *
42  *      Given a string of decimal digits , with optional decimal        *
43  *      mark and optional decimal exponent (place value) of the         *
44  *      lowest_order decimal digit: produce a floating point            *
45  *      number. The number is 'generic' floating point: our             *
46  *      caller will encode it for a specific machine architecture.      *
47  *                                                                      *
48  *      Assumptions                                                     *
49  *              uses base (radix) 2                                     *
50  *              this machine uses 2's complement binary integers        *
51  *              target flonums use "      "         "       "           *
52  *              target flonums exponents fit in a long                  *
53  *                                                                      *
54  \***********************************************************************/
55
56 /*
57
58   Syntax:
59
60   <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
61   <optional-sign> ::= '+' | '-' | {empty}
62   <decimal-number> ::= <integer>
63   | <integer> <radix-character>
64   | <integer> <radix-character> <integer>
65   | <radix-character> <integer>
66
67   <optional-exponent> ::= {empty}
68   | <exponent-character> <optional-sign> <integer>
69
70   <integer> ::= <digit> | <digit> <integer>
71   <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
72   <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
73   <radix-character> ::= {one character from "string_of_decimal_marks"}
74
75   */
76
77 int
78 atof_generic (address_of_string_pointer,
79               string_of_decimal_marks,
80               string_of_decimal_exponent_marks,
81               address_of_generic_floating_point_number)
82      /* return pointer to just AFTER number we read.  */
83      char **address_of_string_pointer;
84      /* At most one per number.  */
85      const char *string_of_decimal_marks;
86      const char *string_of_decimal_exponent_marks;
87      FLONUM_TYPE *address_of_generic_floating_point_number;
88 {
89   int return_value;             /* 0 means OK.  */
90   char *first_digit;
91   unsigned int number_of_digits_before_decimal;
92   unsigned int number_of_digits_after_decimal;
93   long decimal_exponent;
94   unsigned int number_of_digits_available;
95   char digits_sign_char;
96
97   /*
98    * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
99    * It would be simpler to modify the string, but we don't; just to be nice
100    * to caller.
101    * We need to know how many digits we have, so we can allocate space for
102    * the digits' value.
103    */
104
105   char *p;
106   char c;
107   int seen_significant_digit;
108
109 #ifdef ASSUME_DECIMAL_MARK_IS_DOT
110   assert (string_of_decimal_marks[0] == '.'
111           && string_of_decimal_marks[1] == 0);
112 #define IS_DECIMAL_MARK(c)      ((c) == '.')
113 #else
114 #define IS_DECIMAL_MARK(c)      (0 != strchr (string_of_decimal_marks, (c)))
115 #endif
116
117   first_digit = *address_of_string_pointer;
118   c = *first_digit;
119
120   if (c == '-' || c == '+')
121     {
122       digits_sign_char = c;
123       first_digit++;
124     }
125   else
126     digits_sign_char = '+';
127
128   switch (first_digit[0])
129     {
130     case 'n':
131     case 'N':
132       if (!strncasecmp ("nan", first_digit, 3))
133         {
134           address_of_generic_floating_point_number->sign = 0;
135           address_of_generic_floating_point_number->exponent = 0;
136           address_of_generic_floating_point_number->leader =
137             address_of_generic_floating_point_number->low;
138           *address_of_string_pointer = first_digit + 3;
139           return 0;
140         }
141       break;
142
143     case 'i':
144     case 'I':
145       if (!strncasecmp ("inf", first_digit, 3))
146         {
147           address_of_generic_floating_point_number->sign =
148             digits_sign_char == '+' ? 'P' : 'N';
149           address_of_generic_floating_point_number->exponent = 0;
150           address_of_generic_floating_point_number->leader =
151             address_of_generic_floating_point_number->low;
152
153           first_digit += 3;
154           if (!strncasecmp ("inity", first_digit, 5))
155             first_digit += 5;
156
157           *address_of_string_pointer = first_digit;
158
159           return 0;
160         }
161       break;
162     }
163
164   number_of_digits_before_decimal = 0;
165   number_of_digits_after_decimal = 0;
166   decimal_exponent = 0;
167   seen_significant_digit = 0;
168   for (p = first_digit;
169        (((c = *p) != '\0')
170         && (!c || !IS_DECIMAL_MARK (c))
171         && (!c || !strchr (string_of_decimal_exponent_marks, c)));
172        p++)
173     {
174       if (ISDIGIT (c))
175         {
176           if (seen_significant_digit || c > '0')
177             {
178               ++number_of_digits_before_decimal;
179               seen_significant_digit = 1;
180             }
181           else
182             {
183               first_digit++;
184             }
185         }
186       else
187         {
188           break;                /* p -> char after pre-decimal digits.  */
189         }
190     }                           /* For each digit before decimal mark.  */
191
192 #ifndef OLD_FLOAT_READS
193   /* Ignore trailing 0's after the decimal point.  The original code here
194    * (ifdef'd out) does not do this, and numbers like
195    *    4.29496729600000000000e+09      (2**31)
196    * come out inexact for some reason related to length of the digit
197    * string.
198    */
199   if (c && IS_DECIMAL_MARK (c))
200     {
201       unsigned int zeros = 0;   /* Length of current string of zeros */
202
203       for (p++; (c = *p) && ISDIGIT (c); p++)
204         {
205           if (c == '0')
206             {
207               zeros++;
208             }
209           else
210             {
211               number_of_digits_after_decimal += 1 + zeros;
212               zeros = 0;
213             }
214         }
215     }
216 #else
217   if (c && IS_DECIMAL_MARK (c))
218     {
219       for (p++;
220            (((c = *p) != '\0')
221             && (!c || !strchr (string_of_decimal_exponent_marks, c)));
222            p++)
223         {
224           if (ISDIGIT (c))
225             {
226               /* This may be retracted below.  */
227               number_of_digits_after_decimal++;
228
229               if ( /* seen_significant_digit || */ c > '0')
230                 {
231                   seen_significant_digit = TRUE;
232                 }
233             }
234           else
235             {
236               if (!seen_significant_digit)
237                 {
238                   number_of_digits_after_decimal = 0;
239                 }
240               break;
241             }
242         }                       /* For each digit after decimal mark.  */
243     }
244
245   while (number_of_digits_after_decimal
246          && first_digit[number_of_digits_before_decimal
247                         + number_of_digits_after_decimal] == '0')
248     --number_of_digits_after_decimal;
249 #endif
250
251   if (flag_m68k_mri)
252     {
253       while (c == '_')
254         c = *++p;
255     }
256   if (c && strchr (string_of_decimal_exponent_marks, c))
257     {
258       char digits_exponent_sign_char;
259
260       c = *++p;
261       if (flag_m68k_mri)
262         {
263           while (c == '_')
264             c = *++p;
265         }
266       if (c && strchr ("+-", c))
267         {
268           digits_exponent_sign_char = c;
269           c = *++p;
270         }
271       else
272         {
273           digits_exponent_sign_char = '+';
274         }
275
276       for (; (c); c = *++p)
277         {
278           if (ISDIGIT (c))
279             {
280               decimal_exponent = decimal_exponent * 10 + c - '0';
281               /*
282                * BUG! If we overflow here, we lose!
283                */
284             }
285           else
286             {
287               break;
288             }
289         }
290
291       if (digits_exponent_sign_char == '-')
292         {
293           decimal_exponent = -decimal_exponent;
294         }
295     }
296
297   *address_of_string_pointer = p;
298
299   number_of_digits_available =
300     number_of_digits_before_decimal + number_of_digits_after_decimal;
301   return_value = 0;
302   if (number_of_digits_available == 0)
303     {
304       address_of_generic_floating_point_number->exponent = 0;   /* Not strictly necessary */
305       address_of_generic_floating_point_number->leader
306         = -1 + address_of_generic_floating_point_number->low;
307       address_of_generic_floating_point_number->sign = digits_sign_char;
308       /* We have just concocted (+/-)0.0E0 */
309
310     }
311   else
312     {
313       int count;                /* Number of useful digits left to scan.  */
314
315       LITTLENUM_TYPE *digits_binary_low;
316       unsigned int precision;
317       unsigned int maximum_useful_digits;
318       unsigned int number_of_digits_to_use;
319       unsigned int more_than_enough_bits_for_digits;
320       unsigned int more_than_enough_littlenums_for_digits;
321       unsigned int size_of_digits_in_littlenums;
322       unsigned int size_of_digits_in_chars;
323       FLONUM_TYPE power_of_10_flonum;
324       FLONUM_TYPE digits_flonum;
325
326       precision = (address_of_generic_floating_point_number->high
327                    - address_of_generic_floating_point_number->low
328                    + 1);        /* Number of destination littlenums.  */
329
330       /* Includes guard bits (two littlenums worth) */
331 #if 0 /* The integer version below is very close, and it doesn't
332          require floating point support (which is currently buggy on
333          the Alpha).  */
334       maximum_useful_digits = (((double) (precision - 2))
335                                * ((double) (LITTLENUM_NUMBER_OF_BITS))
336                                / (LOG_TO_BASE_2_OF_10))
337         + 2;                    /* 2 :: guard digits.  */
338 #else
339       maximum_useful_digits = (((precision - 2))
340                                * ( (LITTLENUM_NUMBER_OF_BITS))
341                                * 1000000 / 3321928)
342         + 2;                    /* 2 :: guard digits.  */
343 #endif
344
345       if (number_of_digits_available > maximum_useful_digits)
346         {
347           number_of_digits_to_use = maximum_useful_digits;
348         }
349       else
350         {
351           number_of_digits_to_use = number_of_digits_available;
352         }
353
354       /* Cast these to SIGNED LONG first, otherwise, on systems with
355          LONG wider than INT (such as Alpha OSF/1), unsignedness may
356          cause unexpected results.  */
357       decimal_exponent += ((long) number_of_digits_before_decimal
358                            - (long) number_of_digits_to_use);
359
360 #if 0
361       more_than_enough_bits_for_digits
362         = ((((double) number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);
363 #else
364       more_than_enough_bits_for_digits
365         = (number_of_digits_to_use * 3321928 / 1000000 + 1);
366 #endif
367
368       more_than_enough_littlenums_for_digits
369         = (more_than_enough_bits_for_digits
370            / LITTLENUM_NUMBER_OF_BITS)
371         + 2;
372
373       /* Compute (digits) part. In "12.34E56" this is the "1234" part.
374          Arithmetic is exact here. If no digits are supplied then this
375          part is a 0 valued binary integer.  Allocate room to build up
376          the binary number as littlenums.  We want this memory to
377          disappear when we leave this function.  Assume no alignment
378          problems => (room for n objects) == n * (room for 1
379          object).  */
380
381       size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
382       size_of_digits_in_chars = size_of_digits_in_littlenums
383         * sizeof (LITTLENUM_TYPE);
384
385       digits_binary_low = (LITTLENUM_TYPE *)
386         alloca (size_of_digits_in_chars);
387
388       memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
389
390       /* Digits_binary_low[] is allocated and zeroed.  */
391
392       /*
393        * Parse the decimal digits as if * digits_low was in the units position.
394        * Emit a binary number into digits_binary_low[].
395        *
396        * Use a large-precision version of:
397        * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
398        */
399
400       for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
401         {
402           c = *p;
403           if (ISDIGIT (c))
404             {
405               /*
406                * Multiply by 10. Assume can never overflow.
407                * Add this digit to digits_binary_low[].
408                */
409
410               long carry;
411               LITTLENUM_TYPE *littlenum_pointer;
412               LITTLENUM_TYPE *littlenum_limit;
413
414               littlenum_limit = digits_binary_low
415                 + more_than_enough_littlenums_for_digits
416                 - 1;
417
418               carry = c - '0';  /* char -> binary */
419
420               for (littlenum_pointer = digits_binary_low;
421                    littlenum_pointer <= littlenum_limit;
422                    littlenum_pointer++)
423                 {
424                   long work;
425
426                   work = carry + 10 * (long) (*littlenum_pointer);
427                   *littlenum_pointer = work & LITTLENUM_MASK;
428                   carry = work >> LITTLENUM_NUMBER_OF_BITS;
429                 }
430
431               if (carry != 0)
432                 {
433                   /*
434                    * We have a GROSS internal error.
435                    * This should never happen.
436                    */
437                   as_fatal (_("failed sanity check"));
438                 }
439             }
440           else
441             {
442               ++count;          /* '.' doesn't alter digits used count.  */
443             }
444         }
445
446       /*
447        * Digits_binary_low[] properly encodes the value of the digits.
448        * Forget about any high-order littlenums that are 0.
449        */
450       while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
451              && size_of_digits_in_littlenums >= 2)
452         size_of_digits_in_littlenums--;
453
454       digits_flonum.low = digits_binary_low;
455       digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
456       digits_flonum.leader = digits_flonum.high;
457       digits_flonum.exponent = 0;
458       /*
459        * The value of digits_flonum . sign should not be important.
460        * We have already decided the output's sign.
461        * We trust that the sign won't influence the other parts of the number!
462        * So we give it a value for these reasons:
463        * (1) courtesy to humans reading/debugging
464        *     these numbers so they don't get excited about strange values
465        * (2) in future there may be more meaning attached to sign,
466        *     and what was
467        *     harmless noise may become disruptive, ill-conditioned (or worse)
468        *     input.
469        */
470       digits_flonum.sign = '+';
471
472       {
473         /*
474          * Compute the mantssa (& exponent) of the power of 10.
475          * If sucessful, then multiply the power of 10 by the digits
476          * giving return_binary_mantissa and return_binary_exponent.
477          */
478
479         LITTLENUM_TYPE *power_binary_low;
480         int decimal_exponent_is_negative;
481         /* This refers to the "-56" in "12.34E-56".  */
482         /* FALSE: decimal_exponent is positive (or 0) */
483         /* TRUE:  decimal_exponent is negative */
484         FLONUM_TYPE temporary_flonum;
485         LITTLENUM_TYPE *temporary_binary_low;
486         unsigned int size_of_power_in_littlenums;
487         unsigned int size_of_power_in_chars;
488
489         size_of_power_in_littlenums = precision;
490         /* Precision has a built-in fudge factor so we get a few guard bits.  */
491
492         decimal_exponent_is_negative = decimal_exponent < 0;
493         if (decimal_exponent_is_negative)
494           {
495             decimal_exponent = -decimal_exponent;
496           }
497
498         /* From now on: the decimal exponent is > 0. Its sign is separate.  */
499
500         size_of_power_in_chars = size_of_power_in_littlenums
501           * sizeof (LITTLENUM_TYPE) + 2;
502
503         power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
504         temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
505         memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
506         *power_binary_low = 1;
507         power_of_10_flonum.exponent = 0;
508         power_of_10_flonum.low = power_binary_low;
509         power_of_10_flonum.leader = power_binary_low;
510         power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
511         power_of_10_flonum.sign = '+';
512         temporary_flonum.low = temporary_binary_low;
513         temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
514         /*
515          * (power) == 1.
516          * Space for temporary_flonum allocated.
517          */
518
519         /*
520          * ...
521          *
522          * WHILE        more bits
523          * DO   find next bit (with place value)
524          *      multiply into power mantissa
525          * OD
526          */
527         {
528           int place_number_limit;
529           /* Any 10^(2^n) whose "n" exceeds this */
530           /* value will fall off the end of */
531           /* flonum_XXXX_powers_of_ten[].  */
532           int place_number;
533           const FLONUM_TYPE *multiplicand;      /* -> 10^(2^n) */
534
535           place_number_limit = table_size_of_flonum_powers_of_ten;
536
537           multiplicand = (decimal_exponent_is_negative
538                           ? flonum_negative_powers_of_ten
539                           : flonum_positive_powers_of_ten);
540
541           for (place_number = 1;/* Place value of this bit of exponent.  */
542                decimal_exponent;/* Quit when no more 1 bits in exponent.  */
543                decimal_exponent >>= 1, place_number++)
544             {
545               if (decimal_exponent & 1)
546                 {
547                   if (place_number > place_number_limit)
548                     {
549                       /* The decimal exponent has a magnitude so great
550                          that our tables can't help us fragment it.
551                          Although this routine is in error because it
552                          can't imagine a number that big, signal an
553                          error as if it is the user's fault for
554                          presenting such a big number.  */
555                       return_value = ERROR_EXPONENT_OVERFLOW;
556                       /* quit out of loop gracefully */
557                       decimal_exponent = 0;
558                     }
559                   else
560                     {
561 #ifdef TRACE
562                       printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
563                               place_number);
564
565                       flonum_print (&power_of_10_flonum);
566                       (void) putchar ('\n');
567 #endif
568 #ifdef TRACE
569                       printf ("multiplier:\n");
570                       flonum_print (multiplicand + place_number);
571                       (void) putchar ('\n');
572 #endif
573                       flonum_multip (multiplicand + place_number,
574                                      &power_of_10_flonum, &temporary_flonum);
575 #ifdef TRACE
576                       printf ("after multiply:\n");
577                       flonum_print (&temporary_flonum);
578                       (void) putchar ('\n');
579 #endif
580                       flonum_copy (&temporary_flonum, &power_of_10_flonum);
581 #ifdef TRACE
582                       printf ("after copy:\n");
583                       flonum_print (&power_of_10_flonum);
584                       (void) putchar ('\n');
585 #endif
586                     } /* If this bit of decimal_exponent was computable.*/
587                 } /* If this bit of decimal_exponent was set.  */
588             } /* For each bit of binary representation of exponent */
589 #ifdef TRACE
590           printf ("after computing power_of_10_flonum:\n");
591           flonum_print (&power_of_10_flonum);
592           (void) putchar ('\n');
593 #endif
594         }
595
596       }
597
598       /*
599        * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
600        * It may be the number 1, in which case we don't NEED to multiply.
601        *
602        * Multiply (decimal digits) by power_of_10_flonum.
603        */
604
605       flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
606       /* Assert sign of the number we made is '+'.  */
607       address_of_generic_floating_point_number->sign = digits_sign_char;
608
609     }
610   return return_value;
611 }
612
613 #ifdef TRACE
614 static void
615 flonum_print (f)
616      const FLONUM_TYPE *f;
617 {
618   LITTLENUM_TYPE *lp;
619   char littlenum_format[10];
620   sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
621 #define print_littlenum(LP)     (printf (littlenum_format, LP))
622   printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
623   if (f->low < f->high)
624     for (lp = f->high; lp >= f->low; lp--)
625       print_littlenum (*lp);
626   else
627     for (lp = f->low; lp <= f->high; lp++)
628       print_littlenum (*lp);
629   printf ("\n");
630   fflush (stdout);
631 }
632 #endif
633
634 /* end of atof_generic.c */