1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
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
122typedef 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
150typedef 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
161static
162#else
163#if S2F_static < 0 || !defined(S2F_static)
164#if defined(__EXPORT__)
165#define extern		__EXPORT__
166#endif
167extern
168#undef	extern
169#endif
170#endif
171S2F_number
172#if S2F_scan
173#if __STD_C
174S2F_function(void* s, S2F_get_f get)
175#else
176S2F_function(s, get) void* s; S2F_get_f get;
177#endif
178#else
179#if S2F_size
180#if __STD_C
181S2F_function(const char* str, size_t size, char** end)
182#else
183S2F_function(str, size, end) char* str; size_t size; char** end;
184#endif
185#else
186#if __STD_C
187S2F_function(const char* str, char** end)
188#else
189S2F_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	S2F_number		v;
215	S2F_number		p;
216	S2F_part_t		parts[16];
217
218	/*
219	 * radix char and thousands separator are locale specific
220	 */
221
222	SFSETLOCALE(&decimal, &thousand);
223	SFCVINIT();
224
225	/*
226	 * skip initial blanks
227	 */
228
229	do c = GET(s); while (isspace(c));
230	SET(s, t, b);
231
232	/*
233	 * get the sign
234	 */
235
236	if ((negative = (c == '-')) || c == '+')
237		c = GET(s);
238
239	/*
240	 * drop leading 0's
241	 */
242
243	digits = 0;
244	fraction = -1;
245	if (c == '0')
246	{
247		c = GET(s);
248		if (c == 'x' || c == 'X')
249		{
250			/*
251			 * hex floating point -- easy
252			 */
253
254			cv = _Sfcv36;
255			v = 0;
256			for (;;)
257			{
258				c = GET(s);
259				if ((part = cv[c]) < 16)
260				{
261					digits++;
262					v *= 16;
263					v += part;
264				}
265				else if (c == decimal)
266				{
267					decimal = -1;
268					fraction = digits;
269				}
270				else
271					break;
272			}
273			m = 0;
274			if (c == 'p' || c == 'P')
275			{
276				c = GET(s);
277				if ((enegative = c == '-') || c == '+')
278					c = GET(s);
279				while (c >= '0' && c <= '9')
280				{
281					m = (m << 3) + (m << 1) + (c - '0');
282					c = GET(s);
283				}
284				if (enegative)
285					m = -m;
286			}
287
288#if S2F_qualifier
289
290			/*
291			 * consume the optional suffix
292			 */
293
294			switch (c)
295			{
296			case 'f':
297			case 'F':
298			case 'l':
299			case 'L':
300				c = GET(s);
301				break;
302			}
303#endif
304			PUT(s);
305			if (v == 0)
306				return negative ? -v : v;
307			if (fraction >= 0)
308				m -= 4 * (digits - fraction);
309			if (m < S2F_exp_2_min)
310			{
311				if ((m -= S2F_exp_2_min) < S2F_exp_2_min)
312				{
313					ERR(ERANGE);
314					return 0;
315				}
316				v = S2F_ldexp(v, S2F_exp_2_min);
317			}
318			else if (m > S2F_exp_2_max)
319			{
320				ERR(ERANGE);
321				return negative ? -S2F_inf : S2F_inf;
322			}
323			v = S2F_ldexp(v, m);
324			goto check;
325		}
326		while (c == '0')
327			c = GET(s);
328	}
329	else if (c == decimal)
330	{
331		decimal = -1;
332		fraction = 0;
333		for (;;)
334		{
335			c = GET(s);
336			if (c != '0')
337				break;
338			digits++;
339		}
340	}
341	else if (c == 'i' || c == 'I')
342	{
343		if ((c = GET(s)) != 'n' && c != 'N' ||
344		    (c = GET(s)) != 'f' && c != 'F')
345		{
346			REV(s, t, b);
347			PUT(s);
348			return 0;
349		}
350		c = GET(s);
351		SET(s, t, b);
352		if (((c)          == 'i' || c == 'I') &&
353		    ((c = GET(s)) == 'n' || c == 'N') &&
354		    ((c = GET(s)) == 'i' || c == 'I') &&
355		    ((c = GET(s)) == 't' || c == 'T') &&
356		    ((c = GET(s)) == 'y' || c == 'Y'))
357		{
358			c = GET(s);
359			SET(s, t, b);
360		}
361		REV(s, t, b);
362		PUT(s);
363		return negative ? -S2F_inf : S2F_inf;
364	}
365	else if (c == 'n' || c == 'N')
366	{
367		if ((c = GET(s)) != 'a' && c != 'A' ||
368		    (c = GET(s)) != 'n' && c != 'N')
369		{
370			REV(s, t, b);
371			PUT(s);
372			return 0;
373		}
374		do c = GET(s); while (c && !isspace(c));
375		PUT(s);
376		return negative ? -S2F_nan : S2F_nan;
377	}
378	else if (c < '1' || c > '9')
379	{
380		REV(s, t, b);
381		PUT(s);
382		NON(s);
383		return 0;
384	}
385
386	/*
387	 * consume the integral and fractional parts
388	 */
389
390	n = 0;
391	m = 0;
392	for (;;)
393	{
394		if (c >= '0' && c <= '9')
395		{
396			digits++;
397			n = (n << 3) + (n << 1) + (c - '0');
398			if (n >= ((~((S2F_batch)0)) / 10) && part < elementsof(parts))
399			{
400				parts[part].batch = n;
401				n = 0;
402				parts[part].digits = digits;
403				part++;
404			}
405		}
406		else if (m && (digits - m) != 3)
407			break;
408		else if (c == decimal)
409		{
410			decimal = -1;
411			thousand = -1;
412			m = 0;
413			fraction = digits;
414		}
415		else if (c != thousand)
416			break;
417		else if (!(m = digits))
418			break;
419		c = GET(s);
420	}
421
422	/*
423	 * don't forget the last part
424	 */
425
426	if (n && part < elementsof(parts))
427	{
428		parts[part].batch = n;
429		parts[part].digits = digits;
430		part++;
431	}
432
433	/*
434	 * consume the exponent
435	 */
436
437	if (fraction >= 0)
438		digits = fraction;
439	if (c == 'e' || c == 'E')
440	{
441		c = GET(s);
442		if ((enegative = (c == '-')) || c == '+')
443			c = GET(s);
444		n = 0;
445		while (c >= '0' && c <= '9')
446		{
447			n = (n << 3) + (n << 1) + (c - '0');
448			c = GET(s);
449		}
450		if (enegative)
451			digits -= n;
452		else
453			digits += n;
454	}
455
456#if S2F_qualifier
457
458	/*
459	 * consume the optional suffix
460	 */
461
462	switch (c)
463	{
464	case 'f':
465	case 'F':
466	case 'l':
467	case 'L':
468		c = GET(s);
469		break;
470	}
471#endif
472	PUT(s);
473
474	/*
475	 * adjust for at most one multiply per part
476	 * and at most one divide overall
477	 */
478
479	v = 0;
480	if (!part)
481		return negative ? -v : v;
482	else if ((m = parts[part-1].digits - digits) > 0)
483		digits += m;
484	else
485		m = 0;
486
487	/*
488	 * combine the parts
489	 */
490
491	while (part--)
492	{
493		p = parts[part].batch;
494		c = digits - parts[part].digits;
495		if (c > S2F_exp_10_max)
496		{
497			ERR(ERANGE);
498			return negative ? -S2F_inf : S2F_inf;
499		}
500		if (c > 0)
501		{
502#if _ast_mpy_overflow_fpe
503			if ((S2F_max / p) < S2F_pow10[c])
504			{
505				ERR(ERANGE);
506				return negative ? -S2F_inf : S2F_inf;
507			}
508#endif
509			p *= S2F_pow10[c];
510		}
511		v += p;
512	}
513	if (m)
514	{
515		while (m > S2F_exp_10_max)
516		{
517			m -= S2F_exp_10_max;
518			v /= S2F_pow10[S2F_exp_10_max];
519		}
520#if _ast_div_underflow_fpe
521		if ((S2F_min * p) > S2F_pow10[c])
522		{
523			ERR(ERANGE);
524			return negative ? -S2F_inf : S2F_inf;
525		}
526#endif
527		v /= S2F_pow10[m];
528	}
529
530	/*
531	 * check the range
532	 */
533
534 check:
535	if (v < S2F_min)
536	{
537		ERR(ERANGE);
538		v = 0;
539	}
540	else if (v > S2F_max)
541	{
542		ERR(ERANGE);
543		v = S2F_inf;
544	}
545
546	/*
547	 * done
548	 */
549
550	return negative ? -v : v;
551}
552