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 #include "sfhdr.h" 23*4887Schin #include "FEATURE/float" 24*4887Schin 25*4887Schin /* Dealing with $ argument addressing stuffs. 26*4887Schin ** 27*4887Schin ** Written by Kiem-Phong Vo. 28*4887Schin */ 29*4887Schin 30*4887Schin #if __STD_C 31*4887Schin static char* sffmtint(const char* str, int* v) 32*4887Schin #else 33*4887Schin static char* sffmtint(str, v) 34*4887Schin char* str; 35*4887Schin int* v; 36*4887Schin #endif 37*4887Schin { 38*4887Schin for(*v = 0; isdigit(*str); ++str) 39*4887Schin *v = *v * 10 + (*str - '0'); 40*4887Schin *v -= 1; 41*4887Schin return (char*)str; 42*4887Schin } 43*4887Schin 44*4887Schin #if __STD_C 45*4887Schin static Fmtpos_t* sffmtpos(Sfio_t* f,const char* form,va_list args,Sffmt_t* ft,int type) 46*4887Schin #else 47*4887Schin static Fmtpos_t* sffmtpos(f,form,args,ft,type) 48*4887Schin Sfio_t* f; 49*4887Schin char* form; 50*4887Schin va_list args; 51*4887Schin Sffmt_t* ft; 52*4887Schin int type; /* >0: scanf, =0: printf, -1: internal */ 53*4887Schin #endif 54*4887Schin { 55*4887Schin int base, fmt, flags, dot, width, precis; 56*4887Schin ssize_t n_str, size; 57*4887Schin char *t_str, *sp; 58*4887Schin int v, n, skip, dollar, decimal, thousand; 59*4887Schin Sffmt_t savft; 60*4887Schin Fmtpos_t* fp; /* position array of arguments */ 61*4887Schin int argp, argn, maxp, need[FP_INDEX]; 62*4887Schin #if _has_multibyte 63*4887Schin SFMBDCL(fmbs) 64*4887Schin #endif 65*4887Schin 66*4887Schin if(type < 0) 67*4887Schin fp = NIL(Fmtpos_t*); 68*4887Schin else if(!(fp = sffmtpos(f,form,args,ft,-1)) ) 69*4887Schin return NIL(Fmtpos_t*); 70*4887Schin 71*4887Schin dollar = decimal = thousand = 0; argn = maxp = -1; 72*4887Schin SFMBCLR(&fmbs); 73*4887Schin while((n = *form) ) 74*4887Schin { if(n != '%') /* collect the non-pattern chars */ 75*4887Schin { sp = (char*)form; 76*4887Schin for(;;) 77*4887Schin { form += SFMBLEN(form, &fmbs); 78*4887Schin if(*form == 0 || *form == '%') 79*4887Schin break; 80*4887Schin } 81*4887Schin continue; 82*4887Schin } 83*4887Schin else form += 1; 84*4887Schin if(*form == 0) 85*4887Schin break; 86*4887Schin else if(*form == '%') 87*4887Schin { form += 1; 88*4887Schin continue; 89*4887Schin } 90*4887Schin 91*4887Schin if(*form == '*' && type > 0) /* skip in scanning */ 92*4887Schin { skip = 1; 93*4887Schin form += 1; 94*4887Schin argp = -1; 95*4887Schin } 96*4887Schin else /* get the position of this argument */ 97*4887Schin { skip = 0; 98*4887Schin sp = sffmtint(form,&argp); 99*4887Schin if(*sp == '$') 100*4887Schin { dollar = 1; 101*4887Schin form = sp+1; 102*4887Schin } 103*4887Schin else argp = -1; 104*4887Schin } 105*4887Schin 106*4887Schin flags = dot = 0; 107*4887Schin t_str = NIL(char*); n_str = 0; 108*4887Schin size = width = precis = base = -1; 109*4887Schin for(n = 0; n < FP_INDEX; ++n) 110*4887Schin need[n] = -1; 111*4887Schin 112*4887Schin loop_flags: /* LOOP FOR \0, %, FLAGS, WIDTH, PRECISION, BASE, TYPE */ 113*4887Schin switch((fmt = *form++) ) 114*4887Schin { 115*4887Schin case LEFTP : /* get the type enclosed in balanced parens */ 116*4887Schin t_str = (char*)form; 117*4887Schin for(v = 1;;) 118*4887Schin { switch(*form++) 119*4887Schin { 120*4887Schin case 0 : /* not balancable, retract */ 121*4887Schin form = t_str; 122*4887Schin t_str = NIL(char*); 123*4887Schin n_str = 0; 124*4887Schin goto loop_flags; 125*4887Schin case LEFTP : /* increasing nested level */ 126*4887Schin v += 1; 127*4887Schin continue; 128*4887Schin case RIGHTP : /* decreasing nested level */ 129*4887Schin if((v -= 1) != 0) 130*4887Schin continue; 131*4887Schin n_str = form-t_str; 132*4887Schin if(*t_str == '*') 133*4887Schin { t_str = sffmtint(t_str+1,&n); 134*4887Schin if(*t_str == '$') 135*4887Schin dollar = 1; 136*4887Schin else n = -1; 137*4887Schin if((n = FP_SET(n,argn)) > maxp) 138*4887Schin maxp = n; 139*4887Schin if(fp && fp[n].ft.fmt == 0) 140*4887Schin { fp[n].ft.fmt = LEFTP; 141*4887Schin fp[n].ft.form = (char*)form; 142*4887Schin } 143*4887Schin need[FP_STR] = n; 144*4887Schin } 145*4887Schin goto loop_flags; 146*4887Schin } 147*4887Schin } 148*4887Schin 149*4887Schin case '-' : 150*4887Schin flags |= SFFMT_LEFT; 151*4887Schin flags &= ~SFFMT_ZERO; 152*4887Schin goto loop_flags; 153*4887Schin case '0' : 154*4887Schin if(!(flags&SFFMT_LEFT) ) 155*4887Schin flags |= SFFMT_ZERO; 156*4887Schin goto loop_flags; 157*4887Schin case ' ' : 158*4887Schin if(!(flags&SFFMT_SIGN) ) 159*4887Schin flags |= SFFMT_BLANK; 160*4887Schin goto loop_flags; 161*4887Schin case '+' : 162*4887Schin flags |= SFFMT_SIGN; 163*4887Schin flags &= ~SFFMT_BLANK; 164*4887Schin goto loop_flags; 165*4887Schin case '#' : 166*4887Schin flags |= SFFMT_ALTER; 167*4887Schin goto loop_flags; 168*4887Schin case QUOTE: 169*4887Schin SFSETLOCALE(&decimal,&thousand); 170*4887Schin if(thousand > 0) 171*4887Schin flags |= SFFMT_THOUSAND; 172*4887Schin goto loop_flags; 173*4887Schin 174*4887Schin case '.' : 175*4887Schin if((dot += 1) == 2) 176*4887Schin base = 0; /* for %s,%c */ 177*4887Schin if(isdigit(*form)) 178*4887Schin { fmt = *form++; 179*4887Schin goto dot_size; 180*4887Schin } 181*4887Schin else if(*form != '*') 182*4887Schin goto loop_flags; 183*4887Schin else form += 1; /* drop thru below */ 184*4887Schin 185*4887Schin case '*' : 186*4887Schin form = sffmtint(form,&n); 187*4887Schin if(*form == '$' ) 188*4887Schin { dollar = 1; 189*4887Schin form += 1; 190*4887Schin } 191*4887Schin else n = -1; 192*4887Schin if((n = FP_SET(n,argn)) > maxp) 193*4887Schin maxp = n; 194*4887Schin if(fp && fp[n].ft.fmt == 0) 195*4887Schin { fp[n].ft.fmt = '.'; 196*4887Schin fp[n].ft.size = dot; 197*4887Schin fp[n].ft.form = (char*)form; 198*4887Schin } 199*4887Schin if(dot <= 2) 200*4887Schin need[dot] = n; 201*4887Schin goto loop_flags; 202*4887Schin 203*4887Schin case '1' : case '2' : case '3' : 204*4887Schin case '4' : case '5' : case '6' : 205*4887Schin case '7' : case '8' : case '9' : 206*4887Schin dot_size : 207*4887Schin for(v = fmt - '0', fmt = *form; isdigit(fmt); fmt = *++form) 208*4887Schin v = v*10 + (fmt - '0'); 209*4887Schin if(dot == 0) 210*4887Schin width = v; 211*4887Schin else if(dot == 1) 212*4887Schin precis = v; 213*4887Schin else if(dot == 2) 214*4887Schin base = v; 215*4887Schin goto loop_flags; 216*4887Schin 217*4887Schin case 'I' : /* object length */ 218*4887Schin size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_IFLAG; 219*4887Schin if(isdigit(*form) ) 220*4887Schin { for(size = 0, n = *form; isdigit(n); n = *++form) 221*4887Schin size = size*10 + (n - '0'); 222*4887Schin } 223*4887Schin else if(*form == '*') 224*4887Schin { form = sffmtint(form+1,&n); 225*4887Schin if(*form == '$' ) 226*4887Schin { dollar = 1; 227*4887Schin form += 1; 228*4887Schin } 229*4887Schin else n = -1; 230*4887Schin if((n = FP_SET(n,argn)) > maxp) 231*4887Schin maxp = n; 232*4887Schin if(fp && fp[n].ft.fmt == 0) 233*4887Schin { fp[n].ft.fmt = 'I'; 234*4887Schin fp[n].ft.size = sizeof(int); 235*4887Schin fp[n].ft.form = (char*)form; 236*4887Schin } 237*4887Schin need[FP_SIZE] = n; 238*4887Schin } 239*4887Schin goto loop_flags; 240*4887Schin 241*4887Schin case 'l' : 242*4887Schin size = -1; flags &= ~SFFMT_TYPES; 243*4887Schin if(*form == 'l') 244*4887Schin { form += 1; 245*4887Schin flags |= SFFMT_LLONG; 246*4887Schin } 247*4887Schin else flags |= SFFMT_LONG; 248*4887Schin goto loop_flags; 249*4887Schin case 'h' : 250*4887Schin size = -1; flags &= ~SFFMT_TYPES; 251*4887Schin if(*form == 'h') 252*4887Schin { form += 1; 253*4887Schin flags |= SFFMT_SSHORT; 254*4887Schin } 255*4887Schin else flags |= SFFMT_SHORT; 256*4887Schin goto loop_flags; 257*4887Schin case 'L' : 258*4887Schin size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_LDOUBLE; 259*4887Schin goto loop_flags; 260*4887Schin } 261*4887Schin 262*4887Schin /* set object size for scalars */ 263*4887Schin if(flags & SFFMT_TYPES) 264*4887Schin { if((_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT)) || fmt == 'n') 265*4887Schin { if(flags&SFFMT_LONG) 266*4887Schin size = sizeof(long); 267*4887Schin else if(flags&SFFMT_SHORT) 268*4887Schin size = sizeof(short); 269*4887Schin else if(flags&SFFMT_SSHORT) 270*4887Schin size = sizeof(char); 271*4887Schin else if(flags&SFFMT_TFLAG) 272*4887Schin size = sizeof(ptrdiff_t); 273*4887Schin else if(flags&SFFMT_ZFLAG) 274*4887Schin size = sizeof(size_t); 275*4887Schin else if(flags&(SFFMT_LLONG|SFFMT_JFLAG) ) 276*4887Schin size = sizeof(Sflong_t); 277*4887Schin else if(flags&SFFMT_IFLAG) 278*4887Schin { if(size <= 0 || 279*4887Schin size == sizeof(Sflong_t)*CHAR_BIT ) 280*4887Schin size = sizeof(Sflong_t); 281*4887Schin } 282*4887Schin else if(size < 0) 283*4887Schin size = sizeof(int); 284*4887Schin } 285*4887Schin else if(_Sftype[fmt]&SFFMT_FLOAT) 286*4887Schin { if(flags&(SFFMT_LONG|SFFMT_LLONG)) 287*4887Schin size = sizeof(double); 288*4887Schin else if(flags&SFFMT_LDOUBLE) 289*4887Schin size = sizeof(Sfdouble_t); 290*4887Schin else if(flags&SFFMT_IFLAG) 291*4887Schin { if(size <= 0) 292*4887Schin size = sizeof(Sfdouble_t); 293*4887Schin } 294*4887Schin else if(size < 0) 295*4887Schin size = sizeof(float); 296*4887Schin } 297*4887Schin else if(_Sftype[fmt]&SFFMT_CHAR) 298*4887Schin { 299*4887Schin #if _has_multibyte 300*4887Schin if((flags&SFFMT_LONG) || fmt == 'C') 301*4887Schin { size = sizeof(wchar_t) > sizeof(int) ? 302*4887Schin sizeof(wchar_t) : sizeof(int); 303*4887Schin } else 304*4887Schin #endif 305*4887Schin if(size < 0) 306*4887Schin size = sizeof(int); 307*4887Schin } 308*4887Schin } 309*4887Schin 310*4887Schin if(skip) 311*4887Schin continue; 312*4887Schin 313*4887Schin if((argp = FP_SET(argp,argn)) > maxp) 314*4887Schin maxp = argp; 315*4887Schin 316*4887Schin if(dollar && fmt == '!') 317*4887Schin return NIL(Fmtpos_t*); 318*4887Schin 319*4887Schin if(fp && fp[argp].ft.fmt == 0) 320*4887Schin { fp[argp].ft.form = (char*)form; 321*4887Schin fp[argp].ft.fmt = fp[argp].fmt = fmt; 322*4887Schin fp[argp].ft.size = size; 323*4887Schin fp[argp].ft.flags = flags; 324*4887Schin fp[argp].ft.width = width; 325*4887Schin fp[argp].ft.precis = precis; 326*4887Schin fp[argp].ft.base = base; 327*4887Schin fp[argp].ft.t_str = t_str; 328*4887Schin fp[argp].ft.n_str = n_str; 329*4887Schin for(n = 0; n < FP_INDEX; ++n) 330*4887Schin fp[argp].need[n] = need[n]; 331*4887Schin } 332*4887Schin } 333*4887Schin 334*4887Schin if(!fp) /* constructing position array only */ 335*4887Schin { if(!dollar || !(fp = (Fmtpos_t*)malloc((maxp+1)*sizeof(Fmtpos_t))) ) 336*4887Schin return NIL(Fmtpos_t*); 337*4887Schin for(n = 0; n <= maxp; ++n) 338*4887Schin fp[n].ft.fmt = 0; 339*4887Schin return fp; 340*4887Schin } 341*4887Schin 342*4887Schin /* get value for positions */ 343*4887Schin for(n = 0; n <= maxp; ++n) 344*4887Schin { if(fp[n].ft.fmt == 0) /* gap: pretend it's a 'd' pattern */ 345*4887Schin { fp[n].ft.fmt = 'd'; 346*4887Schin fp[n].ft.width = 0; 347*4887Schin fp[n].ft.precis = 0; 348*4887Schin fp[n].ft.base = 0; 349*4887Schin fp[n].ft.size = 0; 350*4887Schin fp[n].ft.t_str = 0; 351*4887Schin fp[n].ft.n_str = 0; 352*4887Schin fp[n].ft.flags = 0; 353*4887Schin for(v = 0; v < FP_INDEX; ++v) 354*4887Schin fp[n].need[v] = -1; 355*4887Schin } 356*4887Schin 357*4887Schin if(ft && ft->extf) 358*4887Schin { fp[n].ft.version = ft->version; 359*4887Schin fp[n].ft.extf = ft->extf; 360*4887Schin fp[n].ft.eventf = ft->eventf; 361*4887Schin if((v = fp[n].need[FP_WIDTH]) >= 0 && v < n) 362*4887Schin fp[n].ft.width = fp[v].argv.i; 363*4887Schin if((v = fp[n].need[FP_PRECIS]) >= 0 && v < n) 364*4887Schin fp[n].ft.precis = fp[v].argv.i; 365*4887Schin if((v = fp[n].need[FP_BASE]) >= 0 && v < n) 366*4887Schin fp[n].ft.base = fp[v].argv.i; 367*4887Schin if((v = fp[n].need[FP_STR]) >= 0 && v < n) 368*4887Schin fp[n].ft.t_str = fp[v].argv.s; 369*4887Schin if((v = fp[n].need[FP_SIZE]) >= 0 && v < n) 370*4887Schin fp[n].ft.size = fp[v].argv.i; 371*4887Schin 372*4887Schin memcpy(ft,&fp[n].ft,sizeof(Sffmt_t)); 373*4887Schin va_copy(ft->args,args); 374*4887Schin ft->flags |= SFFMT_ARGPOS; 375*4887Schin v = (*ft->extf)(f, (Void_t*)(&fp[n].argv), ft); 376*4887Schin va_copy(args,ft->args); 377*4887Schin memcpy(&fp[n].ft,ft,sizeof(Sffmt_t)); 378*4887Schin if(v < 0) 379*4887Schin { memcpy(ft,&savft,sizeof(Sffmt_t)); 380*4887Schin ft = NIL(Sffmt_t*); 381*4887Schin } 382*4887Schin 383*4887Schin if(!(fp[n].ft.flags&SFFMT_VALUE) ) 384*4887Schin goto arg_list; 385*4887Schin else if(_Sftype[fp[n].ft.fmt]&(SFFMT_INT|SFFMT_UINT) ) 386*4887Schin { if(fp[n].ft.size == sizeof(short)) 387*4887Schin { if(_Sftype[fp[n].ft.fmt]&SFFMT_INT) 388*4887Schin fp[n].argv.i = fp[n].argv.h; 389*4887Schin else fp[n].argv.i = fp[n].argv.uh; 390*4887Schin } 391*4887Schin else if(fp[n].ft.size == sizeof(char)) 392*4887Schin { if(_Sftype[fp[n].ft.fmt]&SFFMT_INT) 393*4887Schin fp[n].argv.i = fp[n].argv.c; 394*4887Schin else fp[n].argv.i = fp[n].argv.uc; 395*4887Schin } 396*4887Schin } 397*4887Schin else if(_Sftype[fp[n].ft.fmt]&SFFMT_FLOAT ) 398*4887Schin { if(fp[n].ft.size == sizeof(float) ) 399*4887Schin fp[n].argv.d = fp[n].argv.f; 400*4887Schin } 401*4887Schin } 402*4887Schin else 403*4887Schin { arg_list: 404*4887Schin if(fp[n].ft.fmt == LEFTP) 405*4887Schin { fp[n].argv.s = va_arg(args, char*); 406*4887Schin fp[n].ft.size = strlen(fp[n].argv.s); 407*4887Schin } 408*4887Schin else if(fp[n].ft.fmt == '.' || fp[n].ft.fmt == 'I') 409*4887Schin fp[n].argv.i = va_arg(args, int); 410*4887Schin else if(fp[n].ft.fmt == '!') 411*4887Schin { if(ft) 412*4887Schin memcpy(ft,&savft,sizeof(Sffmt_t)); 413*4887Schin fp[n].argv.ft = ft = va_arg(args, Sffmt_t*); 414*4887Schin if(ft->form) 415*4887Schin ft = NIL(Sffmt_t*); 416*4887Schin if(ft) 417*4887Schin memcpy(&savft,ft,sizeof(Sffmt_t)); 418*4887Schin } 419*4887Schin else if(type > 0) /* from sfvscanf */ 420*4887Schin fp[n].argv.vp = va_arg(args, Void_t*); 421*4887Schin else switch(_Sftype[fp[n].ft.fmt]) 422*4887Schin { case SFFMT_INT: 423*4887Schin case SFFMT_UINT: 424*4887Schin #if !_ast_intmax_long 425*4887Schin if(size == sizeof(Sflong_t) ) 426*4887Schin fp[n].argv.ll = va_arg(args, Sflong_t); 427*4887Schin else 428*4887Schin #endif 429*4887Schin if(size == sizeof(long) ) 430*4887Schin fp[n].argv.l = va_arg(args, long); 431*4887Schin else fp[n].argv.i = va_arg(args, int); 432*4887Schin break; 433*4887Schin case SFFMT_FLOAT: 434*4887Schin #if !_ast_fltmax_double 435*4887Schin if(size == sizeof(Sfdouble_t) ) 436*4887Schin fp[n].argv.ld = va_arg(args,Sfdouble_t); 437*4887Schin else 438*4887Schin #endif 439*4887Schin fp[n].argv.d = va_arg(args,double); 440*4887Schin break; 441*4887Schin case SFFMT_POINTER: 442*4887Schin fp[n].argv.vp = va_arg(args,Void_t*); 443*4887Schin break; 444*4887Schin case SFFMT_CHAR: 445*4887Schin if(fp[n].ft.base >= 0) 446*4887Schin fp[n].argv.s = va_arg(args,char*); 447*4887Schin #if _has_multibyte 448*4887Schin else if((fp[n].ft.flags & SFFMT_LONG) || 449*4887Schin fp[n].ft.fmt == 'C' ) 450*4887Schin { if(sizeof(wchar_t) <= sizeof(int) ) 451*4887Schin fp[n].argv.wc = (wchar_t)va_arg(args,int); 452*4887Schin else fp[n].argv.wc = va_arg(args,wchar_t); 453*4887Schin } 454*4887Schin #endif 455*4887Schin /* observe promotion rule */ 456*4887Schin else fp[n].argv.i = va_arg(args,int); 457*4887Schin break; 458*4887Schin default: /* unknown pattern */ 459*4887Schin break; 460*4887Schin } 461*4887Schin } 462*4887Schin } 463*4887Schin 464*4887Schin if(ft) 465*4887Schin memcpy(ft,&savft,sizeof(Sffmt_t)); 466*4887Schin return fp; 467*4887Schin } 468*4887Schin 469*4887Schin static const unsigned char flt_nan[] = { _ast_flt_nan_init }; 470*4887Schin static const unsigned char flt_inf[] = { _ast_flt_inf_init }; 471*4887Schin static const unsigned char dbl_nan[] = { _ast_dbl_nan_init }; 472*4887Schin static const unsigned char dbl_inf[] = { _ast_dbl_inf_init }; 473*4887Schin #ifdef _ast_ldbl_nan_init 474*4887Schin static const unsigned char ldbl_nan[] = { _ast_ldbl_nan_init }; 475*4887Schin static const unsigned char ldbl_inf[] = { _ast_ldbl_inf_init }; 476*4887Schin #endif 477*4887Schin 478*4887Schin /* function to initialize conversion tables */ 479*4887Schin static int sfcvinit() 480*4887Schin { reg int d, l; 481*4887Schin 482*4887Schin for(d = 0; d <= SF_MAXCHAR; ++d) 483*4887Schin { _Sfcv36[d] = SF_RADIX; 484*4887Schin _Sfcv64[d] = SF_RADIX; 485*4887Schin } 486*4887Schin 487*4887Schin /* [0-9] */ 488*4887Schin for(d = 0; d < 10; ++d) 489*4887Schin { _Sfcv36[(uchar)_Sfdigits[d]] = d; 490*4887Schin _Sfcv64[(uchar)_Sfdigits[d]] = d; 491*4887Schin } 492*4887Schin 493*4887Schin /* [a-z] */ 494*4887Schin for(; d < 36; ++d) 495*4887Schin { _Sfcv36[(uchar)_Sfdigits[d]] = d; 496*4887Schin _Sfcv64[(uchar)_Sfdigits[d]] = d; 497*4887Schin } 498*4887Schin 499*4887Schin /* [A-Z] */ 500*4887Schin for(l = 10; d < 62; ++l, ++d) 501*4887Schin { _Sfcv36[(uchar)_Sfdigits[d]] = l; 502*4887Schin _Sfcv64[(uchar)_Sfdigits[d]] = d; 503*4887Schin } 504*4887Schin 505*4887Schin /* remaining digits */ 506*4887Schin for(; d < SF_RADIX; ++d) 507*4887Schin { _Sfcv36[(uchar)_Sfdigits[d]] = d; 508*4887Schin _Sfcv64[(uchar)_Sfdigits[d]] = d; 509*4887Schin } 510*4887Schin 511*4887Schin _Sftype['d'] = _Sftype['i'] = SFFMT_INT; 512*4887Schin _Sftype['u'] = _Sftype['o'] = _Sftype['x'] = _Sftype['X'] = SFFMT_UINT; 513*4887Schin _Sftype['e'] = _Sftype['E'] = _Sftype['a'] = _Sftype['A'] = 514*4887Schin _Sftype['g'] = _Sftype['G'] = _Sftype['f'] = SFFMT_FLOAT; 515*4887Schin _Sftype['s'] = _Sftype['n'] = _Sftype['p'] = _Sftype['!'] = SFFMT_POINTER; 516*4887Schin _Sftype['c'] = SFFMT_CHAR; 517*4887Schin _Sftype['['] = SFFMT_CLASS; 518*4887Schin #if _has_multibyte 519*4887Schin _Sftype['S'] = SFFMT_POINTER; 520*4887Schin _Sftype['C'] = SFFMT_CHAR; 521*4887Schin #endif 522*4887Schin 523*4887Schin /* IEEE floating point computed constants */ 524*4887Schin 525*4887Schin memcpy((char*)&_Sffnan, (char*)flt_nan, sizeof(_Sffnan)); 526*4887Schin memcpy((char*)&_Sffinf, (char*)flt_inf, sizeof(_Sffinf)); 527*4887Schin memcpy((char*)&_Sfdnan, (char*)dbl_nan, sizeof(_Sfdnan)); 528*4887Schin memcpy((char*)&_Sfdinf, (char*)dbl_inf, sizeof(_Sfdinf)); 529*4887Schin #ifdef _ast_ldbl_nan_init 530*4887Schin memcpy((char*)&_Sflnan, (char*)ldbl_nan, sizeof(_Sflnan)); 531*4887Schin memcpy((char*)&_Sflinf, (char*)ldbl_inf, sizeof(_Sflinf)); 532*4887Schin #else 533*4887Schin memcpy((char*)&_Sflnan, (char*)dbl_nan, sizeof(_Sfdnan)); 534*4887Schin memcpy((char*)&_Sflinf, (char*)dbl_inf, sizeof(_Sfdinf)); 535*4887Schin #endif 536*4887Schin 537*4887Schin return 1; 538*4887Schin } 539*4887Schin 540*4887Schin /* table for floating point and integer conversions */ 541*4887Schin #include "FEATURE/sfinit" 542