1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 /*
23  * AT&T Research
24  * Glenn Fowler & Phong Vo
25  *
26  * common header and implementation for
27  *
28  *	strtof		strtod		strtold		_sfdscan
29  *	strntof		strntod		strntold
30  *
31  * define these macros to instantiate an implementation:
32  *
33  *	S2F_function	the function name
34  *	S2F_static	<0:export =0:extern >0:static
35  *	S2F_type	0:float 1:double 2:long.double
36  *	S2F_qualifier	1 for optional [fFlL] qualifier suffix
37  *	S2F_size	1 for interface with size_t second arg
38  *	S2F_scan	1 for alternate interface with these arguments:
39  *				void* handle
40  *				int (*getchar)(void* handle, int flag)
41  *			exactly one extra (*getchar)() is done, i.e.,
42  *			the caller must do the pushback
43  *				flag==0		get next char
44  *				flag==1		no number seen
45  *			return 0 on error or EOF
46  */
47 
48 #include "sfhdr.h"
49 #include "FEATURE/float"
50 
51 /*
52  * the default is _sfdscan for standalone sfio compatibility
53  */
54 
55 #if !defined(S2F_function)
56 #define S2F_function	_sfdscan
57 #define S2F_static	1
58 #define S2F_type	2
59 #define S2F_scan	1
60 #ifndef elementsof
61 #define elementsof(a)	(sizeof(a)/sizeof(a[0]))
62 #endif
63 #endif
64 
65 #if S2F_type == 2 && _ast_fltmax_double
66 #undef	S2F_type
67 #define S2F_type	1
68 #endif
69 
70 #if S2F_type == 0
71 #define S2F_number	float
72 #define S2F_ldexp	ldexp
73 #define S2F_pow10	_Sffpow10
74 #define S2F_inf		_Sffinf
75 #define S2F_nan		_Sffnan
76 #define S2F_min		(FLT_MIN)
77 #define S2F_max		(FLT_MAX)
78 #define S2F_exp_10_min	(FLT_MIN_10_EXP)
79 #define S2F_exp_10_max	(FLT_MAX_10_EXP)
80 #define S2F_exp_2_min	(FLT_MIN_EXP)
81 #define S2F_exp_2_max	(FLT_MAX_EXP)
82 #endif
83 #if S2F_type == 1
84 #define S2F_number	double
85 #define S2F_ldexp	ldexp
86 #define S2F_pow10	_Sfdpow10
87 #define S2F_inf		_Sfdinf
88 #define S2F_nan		_Sfdnan
89 #define S2F_min		(DBL_MIN)
90 #define S2F_max		(DBL_MAX)
91 #define S2F_exp_10_min	(DBL_MIN_10_EXP)
92 #define S2F_exp_10_max	(DBL_MAX_10_EXP)
93 #define S2F_exp_2_min	(DBL_MIN_EXP)
94 #define S2F_exp_2_max	(DBL_MAX_EXP)
95 #endif
96 #if S2F_type == 2
97 #define S2F_number	long double
98 #define S2F_ldexp	ldexpl
99 #define S2F_pow10	_Sflpow10
100 #define S2F_inf		_Sflinf
101 #define S2F_nan		_Sflnan
102 #define S2F_min		(LDBL_MIN)
103 #define S2F_max		(LDBL_MAX)
104 #define S2F_exp_10_min	(LDBL_MIN_10_EXP)
105 #define S2F_exp_10_max	(LDBL_MAX_10_EXP)
106 #define S2F_exp_2_min	(LDBL_MIN_EXP)
107 #define S2F_exp_2_max	(LDBL_MAX_EXP)
108 #endif
109 
110 #if -S2F_exp_10_min < S2F_exp_10_max
111 #define S2F_exp_10_abs	(-S2F_exp_10_min)
112 #else
113 #define S2F_exp_10_abs	S2F_exp_10_max
114 #endif
115 
116 #define S2F_batch	_ast_flt_unsigned_max_t
117 
118 #undef	ERR		/* who co-opted this namespace? */
119 
120 #if S2F_scan
121 
122 typedef int (*S2F_get_f)_ARG_((void*, int));
123 
124 #define ERR(e)
125 #define GET(p)		(*get)(p,0)
126 #define NON(p)		(*get)(p,1)
127 #define PUT(p)
128 #define REV(p,t,b)
129 #define SET(p,t,b)
130 
131 #else
132 
133 #define ERR(e)		(errno=(e))
134 #define NON(p)
135 
136 #if S2F_size
137 #define GET(p)		(((p)<(z))?(*p++):(back=0))
138 #define PUT(p)		(end?(*end=(char*)p-back):(char*)0)
139 #define REV(p,t,b)	(p=t,back=b)
140 #define SET(p,t,b)	(t=p,b=back)
141 #else
142 #define GET(p)		(*p++)
143 #define PUT(p)		(end?(*end=(char*)p-1):(char*)0)
144 #define REV(p,t,b)	(p=t)
145 #define SET(p,t,b)	(t=p)
146 #endif
147 
148 #endif
149 
150 typedef struct S2F_part_s
151 {
152 	S2F_batch	batch;
153 	int		digits;
154 } S2F_part_t;
155 
156 #if !defined(ERANGE)
157 #define ERANGE		EINVAL
158 #endif
159 
160 #if S2F_static > 0
161 static
162 #else
163 #if S2F_static < 0 || !defined(S2F_static)
164 #if defined(__EXPORT__)
165 #define extern		__EXPORT__
166 #endif
167 extern
168 #undef	extern
169 #endif
170 #endif
171 S2F_number
172 #if S2F_scan
173 #if __STD_C
S2F_function(void * s,S2F_get_f get)174 S2F_function(void* s, S2F_get_f get)
175 #else
176 S2F_function(s, get) void* s; S2F_get_f get;
177 #endif
178 #else
179 #if S2F_size
180 #if __STD_C
181 S2F_function(const char* str, size_t size, char** end)
182 #else
183 S2F_function(str, size, end) char* str; size_t size; char** end;
184 #endif
185 #else
186 #if __STD_C
187 S2F_function(const char* str, char** end)
188 #else
189 S2F_function(str, end) char* str; char** end;
190 #endif
191 #endif
192 #endif
193 {
194 #if !S2F_scan
195 	register unsigned char*	s = (unsigned char*)str;
196 #if S2F_size
197 	register unsigned char*	z = s + size;
198 	int			back = 1;
199 	int			b;
200 #endif
201 	unsigned char*		t;
202 #endif
203 	register S2F_batch	n;
204 	register int		c;
205 	register int		digits;
206 	register int		m;
207 	register unsigned char*	cv;
208 	int			negative;
209 	int			enegative;
210 	int			fraction;
211 	int			decimal = 0;
212 	int			thousand = 0;
213 	int			part = 0;
214 	int			back_part;
215 	S2F_batch		back_n;
216 	S2F_number		v;
217 	S2F_number		p;
218 	S2F_part_t		parts[16];
219 
220 	/*
221 	 * radix char and thousands separator are locale specific
222 	 */
223 
224 	SFSETLOCALE(&decimal, &thousand);
225 	SFCVINIT();
226 
227 	/*
228 	 * skip initial blanks
229 	 */
230 
231 	do c = GET(s); while (isspace(c));
232 	SET(s, t, b);
233 
234 	/*
235 	 * get the sign
236 	 */
237 
238 	if ((negative = (c == '-')) || c == '+')
239 		c = GET(s);
240 
241 	/*
242 	 * drop leading 0's
243 	 */
244 
245 	digits = 0;
246 	fraction = -1;
247 	if (c == '0')
248 	{
249 		c = GET(s);
250 		if (c == 'x' || c == 'X')
251 		{
252 			/*
253 			 * hex floating point -- easy
254 			 */
255 
256 			cv = _Sfcv36;
257 			v = 0;
258 			for (;;)
259 			{
260 				c = GET(s);
261 				if ((part = cv[c]) < 16)
262 				{
263 					digits++;
264 					v *= 16;
265 					v += part;
266 				}
267 				else if (c == decimal)
268 				{
269 					decimal = -1;
270 					fraction = digits;
271 				}
272 				else
273 					break;
274 			}
275 			m = 0;
276 			if (c == 'p' || c == 'P')
277 			{
278 				c = GET(s);
279 				if ((enegative = c == '-') || c == '+')
280 					c = GET(s);
281 				while (c >= '0' && c <= '9')
282 				{
283 					m = (m << 3) + (m << 1) + (c - '0');
284 					c = GET(s);
285 				}
286 				if (enegative)
287 					m = -m;
288 			}
289 
290 #if S2F_qualifier
291 
292 			/*
293 			 * consume the optional suffix
294 			 */
295 
296 			switch (c)
297 			{
298 			case 'f':
299 			case 'F':
300 			case 'l':
301 			case 'L':
302 				c = GET(s);
303 				break;
304 			}
305 #endif
306 			PUT(s);
307 			if (v == 0)
308 				return negative ? -v : v;
309 			if (fraction >= 0)
310 				m -= 4 * (digits - fraction);
311 			if (m < S2F_exp_2_min)
312 			{
313 				if ((m -= S2F_exp_2_min) < S2F_exp_2_min)
314 				{
315 					ERR(ERANGE);
316 					return 0;
317 				}
318 				v = S2F_ldexp(v, S2F_exp_2_min);
319 			}
320 			else if (m > S2F_exp_2_max)
321 			{
322 				ERR(ERANGE);
323 				return negative ? -S2F_inf : S2F_inf;
324 			}
325 			v = S2F_ldexp(v, m);
326 			goto check;
327 		}
328 		while (c == '0')
329 			c = GET(s);
330 	}
331 	else if (c == decimal)
332 	{
333 		decimal = -1;
334 		fraction = 0;
335 		for (;;)
336 		{
337 			c = GET(s);
338 			if (c != '0')
339 				break;
340 			digits++;
341 		}
342 	}
343 	else if (c == 'i' || c == 'I')
344 	{
345 		if ((c = GET(s)) != 'n' && c != 'N' ||
346 		    (c = GET(s)) != 'f' && c != 'F')
347 		{
348 			REV(s, t, b);
349 			PUT(s);
350 			return 0;
351 		}
352 		c = GET(s);
353 		SET(s, t, b);
354 		if (((c)          == 'i' || c == 'I') &&
355 		    ((c = GET(s)) == 'n' || c == 'N') &&
356 		    ((c = GET(s)) == 'i' || c == 'I') &&
357 		    ((c = GET(s)) == 't' || c == 'T') &&
358 		    ((c = GET(s)) == 'y' || c == 'Y'))
359 		{
360 			c = GET(s);
361 			SET(s, t, b);
362 		}
363 		REV(s, t, b);
364 		PUT(s);
365 		return negative ? -S2F_inf : S2F_inf;
366 	}
367 	else if (c == 'n' || c == 'N')
368 	{
369 		if ((c = GET(s)) != 'a' && c != 'A' ||
370 		    (c = GET(s)) != 'n' && c != 'N')
371 		{
372 			REV(s, t, b);
373 			PUT(s);
374 			return 0;
375 		}
376 		do c = GET(s); while (c && !isspace(c));
377 		PUT(s);
378 		return negative ? -S2F_nan : S2F_nan;
379 	}
380 	else if (c < '1' || c > '9')
381 	{
382 		REV(s, t, b);
383 		PUT(s);
384 		NON(s);
385 		return 0;
386 	}
387 
388 	/*
389 	 * consume the integral and fractional parts
390 	 */
391 
392 	n = 0;
393 	m = 0;
394 	for (;;)
395 	{
396 		if (c >= '0' && c <= '9')
397 		{
398 			digits++;
399 			n = (n << 3) + (n << 1) + (c - '0');
400 			if (n >= ((~((S2F_batch)0)) / 10) && part < elementsof(parts))
401 			{
402 				parts[part].batch = n;
403 				n = 0;
404 				parts[part].digits = digits;
405 				part++;
406 			}
407 		}
408 		else if (m && (digits - m) != 3)
409 			break;
410 		else if (c == decimal)
411 		{
412 			decimal = -1;
413 			thousand = -1;
414 			m = 0;
415 			fraction = digits;
416 		}
417 		else if (c != thousand || (c == thousand && decimal == -1))
418 			break;
419 		else if (!(m = digits))
420 		{
421 			SET(s, t, b);
422 			break;
423 		}
424 		else
425 		{
426 			SET(s, t, b);
427 			back_n = n;
428 			back_part = part;
429 		}
430 		c = GET(s);
431 	}
432 	if (m && (digits - m) != 3)
433 	{
434 		REV(s, t, b);
435 		n = back_n;
436 		part = back_part;
437 	}
438 
439 	/*
440 	 * don't forget the last part
441 	 */
442 
443 	if (n && part < elementsof(parts))
444 	{
445 		parts[part].batch = n;
446 		parts[part].digits = digits;
447 		part++;
448 	}
449 
450 	/*
451 	 * consume the exponent
452 	 */
453 
454 	if (fraction >= 0)
455 		digits = fraction;
456 	if (c == 'e' || c == 'E')
457 	{
458 		c = GET(s);
459 		if ((enegative = (c == '-')) || c == '+')
460 			c = GET(s);
461 		n = 0;
462 		while (c >= '0' && c <= '9')
463 		{
464 			n = (n << 3) + (n << 1) + (c - '0');
465 			c = GET(s);
466 		}
467 		if (enegative)
468 			digits -= n;
469 		else
470 			digits += n;
471 	}
472 
473 #if S2F_qualifier
474 
475 	/*
476 	 * consume the optional suffix
477 	 */
478 
479 	switch (c)
480 	{
481 	case 'f':
482 	case 'F':
483 	case 'l':
484 	case 'L':
485 		c = GET(s);
486 		break;
487 	}
488 #endif
489 	PUT(s);
490 
491 	/*
492 	 * adjust for at most one multiply per part
493 	 * and at most one divide overall
494 	 */
495 
496 	v = 0;
497 	if (!part)
498 		return negative ? -v : v;
499 	else if ((m = parts[part-1].digits - digits) > 0)
500 		digits += m;
501 	else
502 		m = 0;
503 
504 	/*
505 	 * combine the parts
506 	 */
507 
508 	while (part--)
509 	{
510 		p = parts[part].batch;
511 		c = digits - parts[part].digits;
512 		if (c > S2F_exp_10_max)
513 		{
514 			ERR(ERANGE);
515 			return negative ? -S2F_inf : S2F_inf;
516 		}
517 		if (c > 0)
518 		{
519 #if _ast_mpy_overflow_fpe
520 			if ((S2F_max / p) < S2F_pow10[c])
521 			{
522 				ERR(ERANGE);
523 				return negative ? -S2F_inf : S2F_inf;
524 			}
525 #endif
526 			p *= S2F_pow10[c];
527 		}
528 		v += p;
529 	}
530 	if (m)
531 	{
532 		while (m > S2F_exp_10_max)
533 		{
534 			m -= S2F_exp_10_max;
535 			v /= S2F_pow10[S2F_exp_10_max];
536 		}
537 #if _ast_div_underflow_fpe
538 		if ((S2F_min * p) > S2F_pow10[c])
539 		{
540 			ERR(ERANGE);
541 			return negative ? -S2F_inf : S2F_inf;
542 		}
543 #endif
544 		v /= S2F_pow10[m];
545 	}
546 
547 	/*
548 	 * check the range
549 	 */
550 
551  check:
552 	if (v < S2F_min)
553 	{
554 		ERR(ERANGE);
555 		v = 0;
556 	}
557 	else if (v > S2F_max)
558 	{
559 		ERR(ERANGE);
560 		v = S2F_inf;
561 	}
562 
563 	/*
564 	 * done
565 	 */
566 
567 	return negative ? -v : v;
568 }
569