|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.