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