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