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