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 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