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