Annotation of researchv10no/libc/stdio/vfprintf.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * pANS stdio -- vfprintf
        !             3:  */
        !             4: #include "iolib.h"
        !             5: #include <stdarg.h>
        !             6: #include <math.h>
        !             7: #include <stdlib.h>
        !             8: #include <string.h>
        !             9: /*
        !            10:  * Leading flags
        !            11:  */
        !            12: #define        SPACE   1               /* ' ' prepend space if no sign printed */
        !            13: #define        ALT     2               /* '#' use alternate conversion */
        !            14: #define        SIGN    4               /* '+' prepend sign, even if positive */
        !            15: #define        LEFT    8               /* '-' left-justify */
        !            16: #define        ZPAD    16              /* '0' zero-pad */
        !            17: /*
        !            18:  * Trailing flags
        !            19:  */
        !            20: #define        SHORT   32              /* 'h' convert a short integer */
        !            21: #define        LONG    64              /* 'l' convert a long integer */
        !            22: #define        LDBL    128             /* 'L' convert a long double */
        !            23: #define        PTR     256             /*     convert a void * (%p) */
        !            24: 
        !            25: static int lflag[] = { /* leading flags */
        !            26: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^@ ^A ^B ^C ^D ^E ^F ^G */
        !            27: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^H ^I ^J ^K ^L ^M ^N ^O */
        !            28: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^P ^Q ^R ^S ^T ^U ^V ^W */
        !            29: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
        !            30: SPACE, 0,      0,      ALT,    0,      0,      0,      0,      /* sp  !  "  #  $  %  &  ' */
        !            31: 0,     0,      0,      SIGN,   0,      LEFT,   0,      0,      /*  (  )  *  +  ,  -  .  / */
        !            32: ZPAD,  0,      0,      0,      0,      0,      0,      0,      /*  0  1  2  3  4  5  6  7 */
        !            33: 0,     0,      0,      0,      0,      0,      0,      0,      /*  8  9  :  ;  <  =  >  ? */
        !            34: 0,     0,      0,      0,      0,      0,      0,      0,      /*  @  A  B  C  D  E  F  G */
        !            35: 0,     0,      0,      0,      0,      0,      0,      0,      /*  H  I  J  K  L  M  N  O */
        !            36: 0,     0,      0,      0,      0,      0,      0,      0,      /*  P  Q  R  S  T  U  V  W */
        !            37: 0,     0,      0,      0,      0,      0,      0,      0,      /*  X  Y  Z  [  \  ]  ^  _ */
        !            38: 0,     0,      0,      0,      0,      0,      0,      0,      /*  `  a  b  c  d  e  f  g */
        !            39: 0,     0,      0,      0,      0,      0,      0,      0,      /*  h  i  j  k  l  m  n  o */
        !            40: 0,     0,      0,      0,      0,      0,      0,      0,      /*  p  q  r  s  t  u  v  w */
        !            41: 0,     0,      0,      0,      0,      0,      0,      0,      /*  x  y  z  {  |  }  ~ ^? */
        !            42: 
        !            43: 0,     0,      0,      0,      0,      0,      0,      0,
        !            44: 0,     0,      0,      0,      0,      0,      0,      0,
        !            45: 0,     0,      0,      0,      0,      0,      0,      0,
        !            46: 0,     0,      0,      0,      0,      0,      0,      0,
        !            47: 0,     0,      0,      0,      0,      0,      0,      0,
        !            48: 0,     0,      0,      0,      0,      0,      0,      0,
        !            49: 0,     0,      0,      0,      0,      0,      0,      0,
        !            50: 0,     0,      0,      0,      0,      0,      0,      0,
        !            51: 0,     0,      0,      0,      0,      0,      0,      0,
        !            52: 0,     0,      0,      0,      0,      0,      0,      0,
        !            53: 0,     0,      0,      0,      0,      0,      0,      0,
        !            54: 0,     0,      0,      0,      0,      0,      0,      0,
        !            55: 0,     0,      0,      0,      0,      0,      0,      0,
        !            56: 0,     0,      0,      0,      0,      0,      0,      0,
        !            57: 0,     0,      0,      0,      0,      0,      0,      0,
        !            58: 0,     0,      0,      0,      0,      0,      0,      0,
        !            59: };
        !            60: 
        !            61: static int tflag[] = { /* trailing flags */
        !            62: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^@ ^A ^B ^C ^D ^E ^F ^G */
        !            63: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^H ^I ^J ^K ^L ^M ^N ^O */
        !            64: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^P ^Q ^R ^S ^T ^U ^V ^W */
        !            65: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
        !            66: 0,     0,      0,      0,      0,      0,      0,      0,      /* sp  !  "  #  $  %  &  ' */
        !            67: 0,     0,      0,      0,      0,      0,      0,      0,      /*  (  )  *  +  ,  -  .  / */
        !            68: 0,     0,      0,      0,      0,      0,      0,      0,      /*  0  1  2  3  4  5  6  7 */
        !            69: 0,     0,      0,      0,      0,      0,      0,      0,      /*  8  9  :  ;  <  =  >  ? */
        !            70: 0,     0,      0,      0,      0,      0,      0,      0,      /*  @  A  B  C  D  E  F  G */
        !            71: 0,     0,      0,      0,      LDBL,   0,      0,      0,      /*  H  I  J  K  L  M  N  O */
        !            72: 0,     0,      0,      0,      0,      0,      0,      0,      /*  P  Q  R  S  T  U  V  W */
        !            73: 0,     0,      0,      0,      0,      0,      0,      0,      /*  X  Y  Z  [  \  ]  ^  _ */
        !            74: 0,     0,      0,      0,      0,      0,      0,      0,      /*  `  a  b  c  d  e  f  g */
        !            75: SHORT, 0,      0,      0,      LONG,   0,      0,      0,      /*  h  i  j  k  l  m  n  o */
        !            76: 0,     0,      0,      0,      0,      0,      0,      0,      /*  p  q  r  s  t  u  v  w */
        !            77: 0,     0,      0,      0,      0,      0,      0,      0,      /*  x  y  z  {  |  }  ~ ^? */
        !            78: 
        !            79: 0,     0,      0,      0,      0,      0,      0,      0,
        !            80: 0,     0,      0,      0,      0,      0,      0,      0,
        !            81: 0,     0,      0,      0,      0,      0,      0,      0,
        !            82: 0,     0,      0,      0,      0,      0,      0,      0,
        !            83: 0,     0,      0,      0,      0,      0,      0,      0,
        !            84: 0,     0,      0,      0,      0,      0,      0,      0,
        !            85: 0,     0,      0,      0,      0,      0,      0,      0,
        !            86: 0,     0,      0,      0,      0,      0,      0,      0,
        !            87: 0,     0,      0,      0,      0,      0,      0,      0,
        !            88: 0,     0,      0,      0,      0,      0,      0,      0,
        !            89: 0,     0,      0,      0,      0,      0,      0,      0,
        !            90: 0,     0,      0,      0,      0,      0,      0,      0,
        !            91: 0,     0,      0,      0,      0,      0,      0,      0,
        !            92: 0,     0,      0,      0,      0,      0,      0,      0,
        !            93: 0,     0,      0,      0,      0,      0,      0,      0,
        !            94: 0,     0,      0,      0,      0,      0,      0,      0,
        !            95: };
        !            96: 
        !            97: static int ocvt_E(FILE *, va_list *, int, int, int);
        !            98: static int ocvt_G(FILE *, va_list *, int, int, int);
        !            99: static int ocvt_X(FILE *, va_list *, int, int, int);
        !           100: static int ocvt_c(FILE *, va_list *, int, int, int);
        !           101: static int ocvt_d(FILE *, va_list *, int, int, int);
        !           102: static int ocvt_e(FILE *, va_list *, int, int, int);
        !           103: static int ocvt_f(FILE *, va_list *, int, int, int);
        !           104: static int ocvt_g(FILE *, va_list *, int, int, int);
        !           105: static int ocvt_n(FILE *, va_list *, int, int, int);
        !           106: static int ocvt_o(FILE *, va_list *, int, int, int);
        !           107: static int ocvt_p(FILE *, va_list *, int, int, int);
        !           108: static int ocvt_s(FILE *, va_list *, int, int, int);
        !           109: static int ocvt_u(FILE *, va_list *, int, int, int);
        !           110: static int ocvt_x(FILE *, va_list *, int, int, int);
        !           111: 
        !           112: static int(*ocvt[])(FILE *, va_list *, int, int, int) = {
        !           113: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^@ ^A ^B ^C ^D ^E ^F ^G */
        !           114: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^H ^I ^J ^K ^L ^M ^N ^O */
        !           115: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^P ^Q ^R ^S ^T ^U ^V ^W */
        !           116: 0,     0,      0,      0,      0,      0,      0,      0,      /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
        !           117: 0,     0,      0,      0,      0,      0,      0,      0,      /* sp  !  "  #  $  %  &  ' */
        !           118: 0,     0,      0,      0,      0,      0,      0,      0,      /*  (  )  *  +  ,  -  .  / */
        !           119: 0,     0,      0,      0,      0,      0,      0,      0,      /*  0  1  2  3  4  5  6  7 */
        !           120: 0,     0,      0,      0,      0,      0,      0,      0,      /*  8  9  :  ;  <  =  >  ? */
        !           121: 0,     0,      0,      0,      0,      ocvt_E, 0,      ocvt_G, /*  @  A  B  C  D  E  F  G */
        !           122: 0,     0,      0,      0,      0,      0,      0,      0,      /*  H  I  J  K  L  M  N  O */
        !           123: 0,     0,      0,      0,      0,      0,      0,      0,      /*  P  Q  R  S  T  U  V  W */
        !           124: ocvt_X,        0,      0,      0,      0,      0,      0,      0,      /*  X  Y  Z  [  \  ]  ^  _ */
        !           125: 0,     0,      0,      ocvt_c, ocvt_d, ocvt_e, ocvt_f, ocvt_g, /*  `  a  b  c  d  e  f  g */
        !           126: 0,     ocvt_d, 0,      0,      0,      0,      ocvt_n, ocvt_o, /*  h  i  j  k  l  m  n  o */
        !           127: ocvt_p,        0,      0,      ocvt_s, 0,      ocvt_u, 0,      0,      /*  p  q  r  s  t  u  v  w */
        !           128: ocvt_x,        0,      0,      0,      0,      0,      0,      0,      /*  x  y  z  {  |  }  ~ ^? */
        !           129: 
        !           130: 0,     0,      0,      0,      0,      0,      0,      0,
        !           131: 0,     0,      0,      0,      0,      0,      0,      0,
        !           132: 0,     0,      0,      0,      0,      0,      0,      0,
        !           133: 0,     0,      0,      0,      0,      0,      0,      0,
        !           134: 0,     0,      0,      0,      0,      0,      0,      0,
        !           135: 0,     0,      0,      0,      0,      0,      0,      0,
        !           136: 0,     0,      0,      0,      0,      0,      0,      0,
        !           137: 0,     0,      0,      0,      0,      0,      0,      0,
        !           138: 0,     0,      0,      0,      0,      0,      0,      0,
        !           139: 0,     0,      0,      0,      0,      0,      0,      0,
        !           140: 0,     0,      0,      0,      0,      0,      0,      0,
        !           141: 0,     0,      0,      0,      0,      0,      0,      0,
        !           142: 0,     0,      0,      0,      0,      0,      0,      0,
        !           143: 0,     0,      0,      0,      0,      0,      0,      0,
        !           144: 0,     0,      0,      0,      0,      0,      0,      0,
        !           145: 0,     0,      0,      0,      0,      0,      0,      0,
        !           146: };
        !           147: 
        !           148: static int nprint;
        !           149: 
        !           150: int
        !           151: vfprintf(FILE *f, const char *s, va_list args)
        !           152: {
        !           153:        int flags, width, precision;
        !           154: 
        !           155:        nprint = 0;
        !           156:        while(*s){
        !           157:                if(*s != '%'){
        !           158:                        putc(*s++, f);
        !           159:                        nprint++;
        !           160:                        continue;
        !           161:                }
        !           162:                s++;
        !           163:                flags = 0;
        !           164:                while(lflag[*s&_IO_CHMASK]) flags |= lflag[*s++&_IO_CHMASK];
        !           165:                if(*s == '*'){
        !           166:                        width = va_arg(args, int);
        !           167:                        s++;
        !           168:                        if(width<0){
        !           169:                                flags |= LEFT;
        !           170:                                width = -width;
        !           171:                        }
        !           172:                }
        !           173:                else{
        !           174:                        width = 0;
        !           175:                        while('0'<=*s && *s<='9') width = width*10 + *s++ - '0';
        !           176:                }
        !           177:                if(*s == '.'){
        !           178:                        s++;
        !           179:                        if(*s == '*'){
        !           180:                                precision = va_arg(args, int);
        !           181:                                s++;
        !           182:                        }
        !           183:                        else{
        !           184:                                precision = 0;
        !           185:                                while('0'<=*s && *s<='9') precision = precision*10 + *s++ - '0';
        !           186:                        }
        !           187:                }
        !           188:                else
        !           189:                        precision = -1;
        !           190:                while(tflag[*s&_IO_CHMASK]) flags |= tflag[*s++&_IO_CHMASK];
        !           191:                if(ocvt[*s]) nprint += (*ocvt[*s++])(f, &args, flags, width, precision);
        !           192:                else if(*s){
        !           193:                        putc(*s++, f);
        !           194:                        nprint++;
        !           195:                }
        !           196:        }
        !           197:        return ferror(f)? -1: nprint;   /* previous errors */
        !           198:                                        /* will be re-reported */
        !           199: }
        !           200: 
        !           201: static int
        !           202: ocvt_c(FILE *f, va_list *args, int flags, int width, int precision)
        !           203: {
        !           204: #pragma ref precision
        !           205:        int i;
        !           206: 
        !           207:        if(!(flags&LEFT)) for(i=1; i<width; i++) putc(' ', f);
        !           208:        putc((unsigned char)va_arg(*args, int), f);
        !           209:        if(flags&LEFT) for(i=1; i<width; i++) putc(' ', f);
        !           210:        return width<1 ? 1 : width;
        !           211: }
        !           212: 
        !           213: static int
        !           214: ocvt_s(FILE *f, va_list *args, int flags, int width, int precision)
        !           215: {
        !           216:        int i, n = 0;
        !           217:        char *s;
        !           218: 
        !           219:        s = va_arg(*args, char *);
        !           220:        if(!(flags&LEFT)){
        !           221:                if(precision >= 0)
        !           222:                        for(i=0; i!=precision && s[i]; i++);
        !           223:                else
        !           224:                        for(i=0; s[i]; i++);
        !           225:                for(; i<width; i++){
        !           226:                        putc(' ', f);
        !           227:                        n++;
        !           228:                }
        !           229:        }
        !           230:        if(precision >= 0){
        !           231:                for(i=0; i!=precision && *s; i++){
        !           232:                        putc(*s++, f);
        !           233:                        n++;
        !           234:                }
        !           235:        } else{
        !           236:                for(i=0;*s;i++){
        !           237:                        putc(*s++, f);
        !           238:                        n++;
        !           239:                }
        !           240:        }
        !           241:        if(flags&LEFT){
        !           242:                for(; i<width; i++){
        !           243:                        putc(' ', f);
        !           244:                        n++;
        !           245:                }
        !           246:        }
        !           247:        return n;
        !           248: }
        !           249: 
        !           250: static int
        !           251: ocvt_n(FILE *f, va_list *args, int flags, int width, int precision)
        !           252: {
        !           253: #pragma ref f
        !           254: #pragma ref width
        !           255: #pragma ref precision
        !           256:        if(flags&SHORT)
        !           257:                *va_arg(*args, short *) = nprint;
        !           258:        else if(flags&LONG)
        !           259:                *va_arg(*args, long *) = nprint;
        !           260:        else
        !           261:                *va_arg(*args, int *) = nprint;
        !           262:        return 0;
        !           263: }
        !           264: 
        !           265: /*
        !           266:  * Generic fixed-point conversion
        !           267:  *     f is the output FILE *;
        !           268:  *     args is the va_list * from which to get the number;
        !           269:  *     flags, width and precision are the results of printf-cracking;
        !           270:  *     radix is the number base to print in;
        !           271:  *     alphabet is the set of digits to use;
        !           272:  *     prefix is the prefix to print before non-zero numbers when
        !           273:  *     using ``alternate form.''
        !           274:  */
        !           275: static int
        !           276: ocvt_fixed(FILE *f, va_list *args, int flags, int width, int precision,
        !           277:        int radix, int sgned, char alphabet[], char *prefix)
        !           278: {
        !           279:        char digits[128];       /* no reasonable machine will ever overflow this */
        !           280:        char *sign;
        !           281:        char *dp;
        !           282:        long snum;
        !           283:        unsigned long num;
        !           284:        int c, nout, npad, nlzero;
        !           285: 
        !           286:        if(sgned){
        !           287:                if(flags&PTR) snum = (long)va_arg(*args, void *);
        !           288:                else if(flags&SHORT) snum = va_arg(*args, short);
        !           289:                else if(flags&LONG) snum = va_arg(*args, long);
        !           290:                else snum = va_arg(*args, int);
        !           291:                if(snum < 0){
        !           292:                        sign = "-";
        !           293:                        num = -snum;
        !           294:                } else{
        !           295:                        if(flags&SIGN) sign = "+";
        !           296:                        else if(flags&SPACE) sign = " ";
        !           297:                        else sign = "";
        !           298:                        num = snum;
        !           299:                }
        !           300:        } else {
        !           301:                sign = "";
        !           302:                if(flags&PTR) num = (long)va_arg(*args, void *);
        !           303:                else if(flags&SHORT) num = va_arg(*args, unsigned short);
        !           304:                else if(flags&LONG) num = va_arg(*args, unsigned long);
        !           305:                else num = va_arg(*args, unsigned int);
        !           306:        }
        !           307:        if(num == 0) prefix = "";
        !           308:        dp = digits;
        !           309:        do{
        !           310:                *dp++ = alphabet[num%radix];
        !           311:                num /= radix;
        !           312:        }while(num);
        !           313:        if(precision==0 && dp-digits==1 && dp[-1]=='0')
        !           314:                dp--;
        !           315:        nlzero = precision-(dp-digits);
        !           316:        if(nlzero < 0) nlzero = 0;
        !           317:        if(flags&ALT){
        !           318:                if(radix == 8) if(dp[-1]=='0' || nlzero) prefix = "";
        !           319:        }
        !           320:        else prefix = "";
        !           321:        nout = dp-digits+nlzero+strlen(prefix)+strlen(sign);
        !           322:        npad = width-nout;
        !           323:        if(npad < 0) npad = 0;
        !           324:        nout += npad;
        !           325:        if(!(flags&LEFT)){
        !           326:                if(flags&ZPAD && precision <= 0){
        !           327:                        /* for sgi, we get a loop if we invoke puts here */
        !           328:                        while(c = *sign++)
        !           329:                                putc(c, f);
        !           330:                        while(c = *prefix++)
        !           331:                                putc(c, f);
        !           332:                        while(npad){
        !           333:                                putc('0', f);
        !           334:                                --npad;
        !           335:                        }
        !           336:                } else{
        !           337:                        while(npad){
        !           338:                                putc(' ', f);
        !           339:                                --npad;
        !           340:                        }
        !           341:                        while(c = *sign++)
        !           342:                                putc(c, f);
        !           343:                        while(c = *prefix++)
        !           344:                                putc(c, f);
        !           345:                }
        !           346:                while(nlzero){
        !           347:                        putc('0', f);
        !           348:                        --nlzero;
        !           349:                }
        !           350:                while(dp!=digits) putc(*--dp, f);
        !           351:        }
        !           352:        else{
        !           353:                while(c = *sign++)
        !           354:                        putc(c, f);
        !           355:                while(c = *prefix++)
        !           356:                        putc(c, f);
        !           357:                while(nlzero){
        !           358:                        putc('0', f);
        !           359:                        --nlzero;
        !           360:                }
        !           361:                while(dp != digits) putc(*--dp, f);
        !           362:                while(npad){
        !           363:                        putc(' ', f);
        !           364:                        --npad;
        !           365:                }
        !           366:        }
        !           367:        return nout;    
        !           368: }
        !           369: 
        !           370: static int
        !           371: ocvt_X(FILE *f, va_list *args, int flags, int width, int precision)
        !           372: {
        !           373:        return ocvt_fixed(f, args, flags, width, precision, 16, 0, "0123456789ABCDEF", "0X");
        !           374: }
        !           375: 
        !           376: static int
        !           377: ocvt_d(FILE *f, va_list *args, int flags, int width, int precision)
        !           378: {
        !           379:        return ocvt_fixed(f, args, flags, width, precision, 10, 1, "0123456789", "");
        !           380: }
        !           381: 
        !           382: static int
        !           383: ocvt_o(FILE *f, va_list *args, int flags, int width, int precision)
        !           384: {
        !           385:        return ocvt_fixed(f, args, flags, width, precision, 8, 0, "01234567", "0");
        !           386: }
        !           387: 
        !           388: static int
        !           389: ocvt_p(FILE *f, va_list *args, int flags, int width, int precision)
        !           390: {
        !           391:        return ocvt_fixed(f, args, flags|PTR|ALT, width, precision, 16, 0,
        !           392:                "0123456789ABCDEF", "0X");
        !           393: }
        !           394: 
        !           395: static int
        !           396: ocvt_u(FILE *f, va_list *args, int flags, int width, int precision)
        !           397: {
        !           398:        return ocvt_fixed(f, args, flags, width, precision, 10, 0, "0123456789", "");
        !           399: }
        !           400: 
        !           401: static int
        !           402: ocvt_x(FILE *f, va_list *args, int flags, int width, int precision)
        !           403: {
        !           404:        return ocvt_fixed(f, args, flags, width, precision, 16, 0, "0123456789abcdef", "0x");
        !           405: }
        !           406: 
        !           407: static int ocvt_flt(FILE *, va_list *, int, int, int, char);
        !           408: 
        !           409: static int
        !           410: ocvt_E(FILE *f, va_list *args, int flags, int width, int precision)
        !           411: {
        !           412:        return ocvt_flt(f, args, flags, width, precision, 'E');
        !           413: }
        !           414: 
        !           415: static int
        !           416: ocvt_G(FILE *f, va_list *args, int flags, int width, int precision)
        !           417: {
        !           418:        return ocvt_flt(f, args, flags, width, precision, 'G');
        !           419: }
        !           420: 
        !           421: static int
        !           422: ocvt_e(FILE *f, va_list *args, int flags, int width, int precision)
        !           423: {
        !           424:        return ocvt_flt(f, args, flags, width, precision, 'e');
        !           425: }
        !           426: 
        !           427: static int
        !           428: ocvt_f(FILE *f, va_list *args, int flags, int width, int precision)
        !           429: {
        !           430:        return ocvt_flt(f, args, flags, width, precision, 'f');
        !           431: }
        !           432: 
        !           433: static int
        !           434: ocvt_g(FILE *f, va_list *args, int flags, int width, int precision)
        !           435: {
        !           436:        return ocvt_flt(f, args, flags, width, precision, 'g');
        !           437: }
        !           438: 
        !           439: static int
        !           440: ocvt_flt(FILE *f, va_list *args, int flags, int width, int precision, char afmt)
        !           441: {
        !           442:        extern char *_dtoa(double, int, int, int*, int*, char **);
        !           443:        int echr;
        !           444:        char *digits, *edigits;
        !           445:        int exponent;
        !           446:        char fmt;
        !           447:        int sign;
        !           448:        int ndig;
        !           449:        int nout, i;
        !           450:        char ebuf[20];  /* no sensible machine will overflow this */
        !           451:        char *eptr;
        !           452:        double d;
        !           453: 
        !           454:        echr = 'e';
        !           455:        fmt = afmt;
        !           456:        d = va_arg(*args, double);
        !           457:        if(precision < 0) precision = 6;
        !           458:        switch(fmt){
        !           459:        case 'f':
        !           460:                digits = _dtoa(d, 3, precision, &exponent, &sign, &edigits);
        !           461:                break;
        !           462:        case 'E':
        !           463:                echr = 'E';
        !           464:                fmt = 'e';
        !           465:                /* fall through */
        !           466:        case 'e':
        !           467:                digits = _dtoa(d, 2, 1+precision, &exponent, &sign, &edigits);
        !           468:                break;
        !           469:        case 'G':
        !           470:                echr = 'E';
        !           471:                /* fall through */
        !           472:        case 'g':
        !           473:                if (precision > 0)
        !           474:                        digits = _dtoa(d, 2, precision, &exponent, &sign, &edigits);
        !           475:                else {
        !           476:                        digits = _dtoa(d, 0, precision, &exponent, &sign, &edigits);
        !           477:                        precision = edigits - digits;
        !           478:                        if (exponent > precision && exponent <= precision + 4)
        !           479:                                precision = exponent;
        !           480:                        }
        !           481:                if(exponent >= -3 && exponent <= precision){
        !           482:                        fmt = 'f';
        !           483:                        precision -= exponent;
        !           484:                }else{
        !           485:                        fmt = 'e';
        !           486:                        --precision;
        !           487:                }
        !           488:                break;
        !           489:        }
        !           490:        if (exponent == 9999) {
        !           491:                /* Infinity or Nan */
        !           492:                precision = 0;
        !           493:                exponent = edigits - digits;
        !           494:                fmt = 'f';
        !           495:        }
        !           496:        ndig = edigits-digits;
        !           497:        if((afmt=='g' || afmt=='G') && !(flags&ALT)){   /* knock off trailing zeros */
        !           498:                if(fmt == 'f'){
        !           499:                        if(precision+exponent > ndig) {
        !           500:                                precision = ndig - exponent;
        !           501:                                if(precision < 0)
        !           502:                                        precision = 0;
        !           503:                        }
        !           504:                }
        !           505:                else{
        !           506:                        if(precision > ndig-1) precision = ndig-1;
        !           507:                }
        !           508:        }
        !           509:        nout = precision;                               /* digits after decimal point */
        !           510:        if(precision!=0 || flags&ALT) nout++;           /* decimal point */
        !           511:        if(fmt=='f' && exponent>0) nout += exponent;    /* digits before decimal point */
        !           512:        else nout++;                                    /* there's always at least one */
        !           513:        if(sign || flags&(SPACE|SIGN)) nout++;          /* sign */
        !           514:        if(fmt != 'f'){                                 /* exponent */
        !           515:                eptr = ebuf;
        !           516:                for(i=exponent<=0?1-exponent:exponent-1; i; i/=10)
        !           517:                        *eptr++ = '0' + i%10;
        !           518:                while(eptr<ebuf+2) *eptr++ = '0';
        !           519:                nout += eptr-ebuf+2;                    /* e+99 */
        !           520:        }
        !           521:        if(!(flags&ZPAD) && !(flags&LEFT))
        !           522:                while(nout < width){
        !           523:                        putc(' ', f);
        !           524:                        nout++;
        !           525:                }
        !           526:        if(sign) putc('-', f);
        !           527:        else if(flags&SIGN) putc('+', f);
        !           528:        else if(flags&SPACE) putc(' ', f);
        !           529:        if(flags&ZPAD)
        !           530:                while(nout < width){
        !           531:                        putc('0', f);
        !           532:                        nout++;
        !           533:                }
        !           534:        if(fmt == 'f'){
        !           535:                for(i=0; i<exponent; i++) putc(i<ndig?digits[i]:'0', f);
        !           536:                if(i == 0) putc('0', f);
        !           537:                if(precision>0 || flags&ALT) putc('.', f);
        !           538:                for(i=0; i!=precision; i++)
        !           539:                        putc(0<=i+exponent && i+exponent<ndig?digits[i+exponent]:'0', f);
        !           540:        }
        !           541:        else{
        !           542:                putc(digits[0], f);
        !           543:                if(precision>0 || flags&ALT) putc('.', f);
        !           544:                for(i=0; i!=precision; i++) putc(i<ndig-1?digits[i+1]:'0', f);
        !           545:        }
        !           546:        if(fmt != 'f'){
        !           547:                putc(echr, f);
        !           548:                putc(exponent<=0?'-':'+', f);
        !           549:                while(eptr>ebuf) putc(*--eptr, f);
        !           550:        }
        !           551:        while(nout < width){
        !           552:                putc(' ', f);
        !           553:                nout++;
        !           554:        }
        !           555:        return nout;
        !           556: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.