00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include <sys/types.h>
00064 #define u_long unsigned long
00065 #define u_short unsigned short
00066 #define u_int unsigned int
00067
00068 #if !defined(HAVE_STDARG_PROTOTYPES)
00069 #if defined(__STDC__)
00070 #define HAVE_STDARG_PROTOTYPES 1
00071 #endif
00072 #endif
00073
00074 #undef __P
00075 #if defined(HAVE_STDARG_PROTOTYPES)
00076 # include <stdarg.h>
00077 # if !defined(__P)
00078 # define __P(x) x
00079 # endif
00080 #else
00081 # define __P(x) ()
00082 # if !defined(const)
00083 # define const
00084 # endif
00085 # include <varargs.h>
00086 #endif
00087 #ifndef _BSD_VA_LIST_
00088 #define _BSD_VA_LIST_ va_list
00089 #endif
00090
00091 #ifdef __STDC__
00092 # include <limits.h>
00093 #else
00094 # ifndef LONG_MAX
00095 # ifdef HAVE_LIMITS_H
00096 # include <limits.h>
00097 # else
00098
00099 # define LONG_MAX 2147483647
00100 # endif
00101 # endif
00102 #endif
00103
00104 #if defined(__hpux) && !defined(__GNUC__) && !defined(__STDC__)
00105 #define const
00106 #endif
00107
00108 #if defined(sgi)
00109 #undef __const
00110 #define __const
00111 #endif
00112
00113 #include <stddef.h>
00114 #if defined(__hpux) && !defined(__GNUC__) || defined(__DECC)
00115 #include <string.h>
00116 #endif
00117
00118 #if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__)
00119 #include <stdlib.h>
00120 #endif
00121
00122 #ifndef NULL
00123 #define NULL 0
00124 #endif
00125
00126 #if SIZEOF_LONG > SIZEOF_INT
00127 # include <errno.h>
00128 #endif
00129
00130
00131
00132
00133
00134
00135
00136
00137 struct __sbuf {
00138 unsigned char *_base;
00139 size_t _size;
00140 };
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 typedef struct __sFILE {
00170 unsigned char *_p;
00171 #if 0
00172 size_t _r;
00173 #endif
00174 size_t _w;
00175 short _flags;
00176 short _file;
00177 struct __sbuf _bf;
00178 size_t _lbfsize;
00179 int (*vwrite)();
00180 } FILE;
00181
00182
00183 #define __SLBF 0x0001
00184 #define __SNBF 0x0002
00185 #define __SRD 0x0004
00186 #define __SWR 0x0008
00187
00188 #define __SRW 0x0010
00189 #define __SEOF 0x0020
00190 #define __SERR 0x0040
00191 #define __SMBF 0x0080
00192 #define __SAPP 0x0100
00193 #define __SSTR 0x0200
00194 #define __SOPT 0x0400
00195 #define __SNPT 0x0800
00196 #define __SOFF 0x1000
00197 #define __SMOD 0x2000
00198
00199
00200 #define EOF (-1)
00201
00202
00203 #define __sfeof(p) (((p)->_flags & __SEOF) != 0)
00204 #define __sferror(p) (((p)->_flags & __SERR) != 0)
00205 #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
00206 #define __sfileno(p) ((p)->_file)
00207
00208 #undef feof
00209 #undef ferror
00210 #undef clearerr
00211 #define feof(p) __sfeof(p)
00212 #define ferror(p) __sferror(p)
00213 #define clearerr(p) __sclearerr(p)
00214
00215 #ifndef _ANSI_SOURCE
00216 #define fileno(p) __sfileno(p)
00217 #endif
00218
00219
00220
00221
00222
00223 struct __siov {
00224 const void *iov_base;
00225 size_t iov_len;
00226 };
00227 struct __suio {
00228 struct __siov *uio_iov;
00229 int uio_iovcnt;
00230 size_t uio_resid;
00231 };
00232
00233
00234
00235
00236
00237
00238
00239 static int BSD__sfvwrite(fp, uio)
00240 register FILE *fp;
00241 register struct __suio *uio;
00242 {
00243 register size_t len;
00244 register const char *p;
00245 register struct __siov *iov;
00246 register size_t w;
00247
00248 if ((len = uio->uio_resid) == 0)
00249 return (0);
00250 #ifndef __hpux
00251 #define MIN(a, b) ((a) < (b) ? (a) : (b))
00252 #endif
00253 #define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
00254
00255 iov = uio->uio_iov;
00256 p = iov->iov_base;
00257 len = iov->iov_len;
00258 iov++;
00259 #define GETIOV(extra_work) \
00260 while (len == 0) { \
00261 extra_work; \
00262 p = iov->iov_base; \
00263 len = iov->iov_len; \
00264 iov++; \
00265 }
00266 if (fp->_flags & __SNBF) {
00267
00268
00269
00270 } else if ((fp->_flags & __SLBF) == 0) {
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 do {
00283 GETIOV(;);
00284 w = fp->_w;
00285 if (fp->_flags & __SSTR) {
00286 if (len < w)
00287 w = len;
00288 COPY(w);
00289 fp->_w -= w;
00290 fp->_p += w;
00291 w = len;
00292 } else {
00293
00294
00295
00296 }
00297 p += w;
00298 len -= w;
00299 } while ((uio->uio_resid -= w) != 0);
00300 } else {
00301
00302
00303
00304 }
00305 return (0);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 static int
00319 BSD__sprint(FILE *fp, register struct __suio *uio)
00320 {
00321 register int err;
00322
00323 if (uio->uio_resid == 0) {
00324 uio->uio_iovcnt = 0;
00325 return (0);
00326 }
00327 err = (*fp->vwrite)(fp, uio);
00328 uio->uio_resid = 0;
00329 uio->uio_iovcnt = 0;
00330 return (err);
00331 }
00332
00333
00334
00335
00336
00337
00338
00339 static int
00340 BSD__sbprintf(register FILE *fp, const char *fmt, va_list ap)
00341 {
00342
00343 return 0;
00344 }
00345
00346
00347
00348
00349
00350 #define to_digit(c) ((c) - '0')
00351 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
00352 #define to_char(n) (char)((n) + '0')
00353
00354 #ifdef _HAVE_SANE_QUAD_
00355
00356
00357
00358
00359
00360
00361 static char *
00362 BSD__uqtoa(register u_quad_t val, char *endp, int base, int octzero, const char *xdigs)
00363 {
00364 register char *cp = endp;
00365 register long sval;
00366
00367
00368
00369
00370
00371 switch (base) {
00372 case 10:
00373 if (val < 10) {
00374 *--cp = to_char(val);
00375 return (cp);
00376 }
00377
00378
00379
00380
00381
00382
00383 if (val > LLONG_MAX) {
00384 *--cp = to_char(val % 10);
00385 sval = val / 10;
00386 } else
00387 sval = val;
00388 do {
00389 *--cp = to_char(sval % 10);
00390 sval /= 10;
00391 } while (sval != 0);
00392 break;
00393
00394 case 8:
00395 do {
00396 *--cp = to_char(val & 7);
00397 val >>= 3;
00398 } while (val);
00399 if (octzero && *cp != '0')
00400 *--cp = '0';
00401 break;
00402
00403 case 16:
00404 do {
00405 *--cp = xdigs[val & 15];
00406 val >>= 4;
00407 } while (val);
00408 break;
00409
00410 default:
00411
00412
00413
00414 break;
00415 }
00416 return (cp);
00417 }
00418 #endif
00419
00420
00421
00422
00423
00424
00425
00426 static char *
00427 BSD__ultoa(register u_long val, char *endp, int base, int octzero, const char *xdigs)
00428 {
00429 register char *cp = endp;
00430 register long sval;
00431
00432
00433
00434
00435
00436 switch (base) {
00437 case 10:
00438 if (val < 10) {
00439 *--cp = to_char(val);
00440 return (cp);
00441 }
00442
00443
00444
00445
00446
00447
00448 if (val > LONG_MAX) {
00449 *--cp = to_char(val % 10);
00450 sval = val / 10;
00451 } else
00452 sval = val;
00453 do {
00454 *--cp = to_char(sval % 10);
00455 sval /= 10;
00456 } while (sval != 0);
00457 break;
00458
00459 case 8:
00460 do {
00461 *--cp = to_char(val & 7);
00462 val >>= 3;
00463 } while (val);
00464 if (octzero && *cp != '0')
00465 *--cp = '0';
00466 break;
00467
00468 case 16:
00469 do {
00470 *--cp = xdigs[val & 15];
00471 val >>= 4;
00472 } while (val);
00473 break;
00474
00475 default:
00476
00477
00478
00479 break;
00480 }
00481 return (cp);
00482 }
00483
00484 #ifdef FLOATING_POINT
00485 #include <math.h>
00486
00487
00488 #ifndef MAXEXP
00489 # define MAXEXP 1024
00490 #endif
00491
00492 #ifndef MAXFRACT
00493 # define MAXFRACT 64
00494 #endif
00495
00496 #define BUF (MAXEXP+MAXFRACT+1)
00497 #define DEFPREC 6
00498
00499 static char *cvt __P((double, int, int, char *, int *, int, int *, char *));
00500 static int exponent __P((char *, int, int));
00501
00502 #else
00503
00504 #define BUF 68
00505
00506 #endif
00507
00508
00509
00510
00511
00512 #define ALT 0x001
00513 #define HEXPREFIX 0x002
00514 #define LADJUST 0x004
00515 #define LONGDBL 0x008
00516 #define LONGINT 0x010
00517
00518 #ifdef _HAVE_SANE_QUAD_
00519 #define QUADINT 0x020
00520 #endif
00521
00522 #define SHORTINT 0x040
00523 #define ZEROPAD 0x080
00524 #define FPT 0x100
00525 static ssize_t
00526 BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
00527 {
00528 register const char *fmt;
00529 register int ch;
00530 register int n;
00531 register const char *cp;
00532 register struct __siov *iovp;
00533 register int flags;
00534 ssize_t ret;
00535 int width;
00536 int prec;
00537 char sign;
00538 #ifdef FLOATING_POINT
00539 char softsign;
00540 double _double = 0;
00541 int expt;
00542 int expsize = 0;
00543 int ndig = 0;
00544 char expstr[7];
00545 #endif
00546 u_long ulval;
00547 #ifdef _HAVE_SANE_QUAD_
00548 u_quad_t uqval;
00549 #endif
00550 int base;
00551 int dprec;
00552 long fieldsz;
00553 long realsz;
00554 int size;
00555 const char *xdigs = 0;
00556 #define NIOV 8
00557 struct __suio uio;
00558 struct __siov iov[NIOV];
00559 char buf[BUF];
00560 char ox[4];
00561 char *const ebuf = buf + sizeof(buf);
00562 #if SIZEOF_LONG > SIZEOF_INT
00563 long ln;
00564 #endif
00565
00566
00567
00568
00569
00570
00571 #define PADSIZE 16
00572 static const char blanks[PADSIZE] =
00573 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
00574 static const char zeroes[PADSIZE] =
00575 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
00576
00577
00578
00579
00580 #define PRINT(ptr, len) { \
00581 iovp->iov_base = (ptr); \
00582 iovp->iov_len = (len); \
00583 uio.uio_resid += (len); \
00584 iovp++; \
00585 if (++uio.uio_iovcnt >= NIOV) { \
00586 if (BSD__sprint(fp, &uio)) \
00587 goto error; \
00588 iovp = iov; \
00589 } \
00590 }
00591 #define PAD(howmany, with) { \
00592 if ((n = (howmany)) > 0) { \
00593 while (n > PADSIZE) { \
00594 PRINT(with, PADSIZE); \
00595 n -= PADSIZE; \
00596 } \
00597 PRINT(with, n); \
00598 } \
00599 }
00600 #if SIZEOF_LONG > SIZEOF_INT
00601
00602 #define PAD_L(howmany, with) { \
00603 ln = (howmany); \
00604 if ((long)((int)ln) != ln) { \
00605 errno = ENOMEM; \
00606 goto error; \
00607 } \
00608 if (ln > 0) PAD((int)ln, with); \
00609 }
00610 #else
00611 #define PAD_L(howmany, with) PAD(howmany, with)
00612 #endif
00613 #define FLUSH() { \
00614 if (uio.uio_resid && BSD__sprint(fp, &uio)) \
00615 goto error; \
00616 uio.uio_iovcnt = 0; \
00617 iovp = iov; \
00618 }
00619
00620
00621
00622
00623
00624 #define SARG() \
00625 (flags&LONGINT ? va_arg(ap, long) : \
00626 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
00627 (long)va_arg(ap, int))
00628 #define UARG() \
00629 (flags&LONGINT ? va_arg(ap, u_long) : \
00630 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
00631 (u_long)va_arg(ap, u_int))
00632
00633
00634 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
00635 fp->_file >= 0)
00636 return (BSD__sbprintf(fp, fmt0, ap));
00637
00638 fmt = fmt0;
00639 uio.uio_iov = iovp = iov;
00640 uio.uio_resid = 0;
00641 uio.uio_iovcnt = 0;
00642 ret = 0;
00643 xdigs = 0;
00644
00645
00646
00647
00648 for (;;) {
00649 size_t nc;
00650 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
00651 ;
00652 if ((nc = fmt - cp) != 0) {
00653 PRINT(cp, nc);
00654 ret += nc;
00655 }
00656 if (ch == '\0')
00657 goto done;
00658 fmt++;
00659
00660 flags = 0;
00661 dprec = 0;
00662 width = 0;
00663 prec = -1;
00664 sign = '\0';
00665
00666 rflag: ch = *fmt++;
00667 reswitch: switch (ch) {
00668 case ' ':
00669
00670
00671
00672
00673
00674 if (!sign)
00675 sign = ' ';
00676 goto rflag;
00677 case '#':
00678 flags |= ALT;
00679 goto rflag;
00680 case '*':
00681
00682
00683
00684
00685
00686
00687 if ((width = va_arg(ap, int)) >= 0)
00688 goto rflag;
00689 width = -width;
00690
00691 case '-':
00692 flags |= LADJUST;
00693 goto rflag;
00694 case '+':
00695 sign = '+';
00696 goto rflag;
00697 case '.':
00698 if ((ch = *fmt++) == '*') {
00699 n = va_arg(ap, int);
00700 prec = n < 0 ? -1 : n;
00701 goto rflag;
00702 }
00703 n = 0;
00704 while (is_digit(ch)) {
00705 n = 10 * n + to_digit(ch);
00706 ch = *fmt++;
00707 }
00708 prec = n < 0 ? -1 : n;
00709 goto reswitch;
00710 case '0':
00711
00712
00713
00714
00715
00716 flags |= ZEROPAD;
00717 goto rflag;
00718 case '1': case '2': case '3': case '4':
00719 case '5': case '6': case '7': case '8': case '9':
00720 n = 0;
00721 do {
00722 n = 10 * n + to_digit(ch);
00723 ch = *fmt++;
00724 } while (is_digit(ch));
00725 width = n;
00726 goto reswitch;
00727 #ifdef FLOATING_POINT
00728 case 'L':
00729 flags |= LONGDBL;
00730 goto rflag;
00731 #endif
00732 case 'h':
00733 flags |= SHORTINT;
00734 goto rflag;
00735 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG
00736 case 't':
00737 #endif
00738 #if SIZEOF_SIZE_T == SIZEOF_LONG
00739 case 'z':
00740 #endif
00741 case 'l':
00742 flags |= LONGINT;
00743 goto rflag;
00744 #ifdef _HAVE_SANE_QUAD_
00745 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
00746 case 't':
00747 #endif
00748 #if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
00749 case 'z':
00750 #endif
00751 case 'q':
00752 flags |= QUADINT;
00753 goto rflag;
00754 #endif
00755 case 'c':
00756 cp = buf;
00757 *buf = (char)va_arg(ap, int);
00758 size = 1;
00759 sign = '\0';
00760 break;
00761 case 'D':
00762 flags |= LONGINT;
00763
00764 case 'd':
00765 case 'i':
00766 #ifdef _HAVE_SANE_QUAD_
00767 if (flags & QUADINT) {
00768 uqval = va_arg(ap, quad_t);
00769 if ((quad_t)uqval < 0) {
00770 uqval = -(quad_t)uqval;
00771 sign = '-';
00772 }
00773 } else
00774 #endif
00775 {
00776 ulval = SARG();
00777 if ((long)ulval < 0) {
00778 ulval = (u_long)(-(long)ulval);
00779 sign = '-';
00780 }
00781 }
00782 base = 10;
00783 goto number;
00784 #ifdef FLOATING_POINT
00785 case 'a':
00786 case 'A':
00787 if (prec >= 0)
00788 prec++;
00789 goto fp_begin;
00790 case 'e':
00791 case 'E':
00792 if (prec != 0)
00793 flags |= ALT;
00794 prec = (prec == -1) ?
00795 DEFPREC + 1 : prec + 1;
00796
00797 goto fp_begin;
00798 case 'f':
00799 if (prec != 0)
00800 flags |= ALT;
00801 case 'g':
00802 case 'G':
00803 if (prec == -1)
00804 prec = DEFPREC;
00805 fp_begin: _double = va_arg(ap, double);
00806
00807 if (isinf(_double)) {
00808 if (_double < 0)
00809 sign = '-';
00810 cp = "Inf";
00811 size = 3;
00812 break;
00813 }
00814 if (isnan(_double)) {
00815 cp = "NaN";
00816 size = 3;
00817 break;
00818 }
00819 flags |= FPT;
00820 cp = cvt(_double, prec, flags, &softsign,
00821 &expt, ch, &ndig, buf);
00822 if (ch == 'g' || ch == 'G') {
00823 if (expt <= -4 || (expt > prec && expt > 1))
00824 ch = (ch == 'g') ? 'e' : 'E';
00825 else
00826 ch = 'g';
00827 }
00828 if (ch == 'a' || ch == 'A') {
00829 --expt;
00830 expsize = exponent(expstr, expt, ch + 'p' - 'a');
00831 size = expsize + ndig;
00832 }
00833 else if (ch <= 'e') {
00834 --expt;
00835 expsize = exponent(expstr, expt, ch);
00836 size = expsize + ndig;
00837 if (ndig > 1 || flags & ALT)
00838 ++size;
00839 } else if (ch == 'f') {
00840 if (expt > 0) {
00841 size = expt;
00842 if (prec || flags & ALT)
00843 size += prec + 1;
00844 } else if (!prec) {
00845 size = 1;
00846 } else
00847 size = prec + 2;
00848 } else if (expt >= ndig) {
00849 size = expt;
00850 if (flags & ALT)
00851 ++size;
00852 } else
00853 size = ndig + (expt > 0 ?
00854 1 : 2 - expt);
00855
00856 if (softsign)
00857 sign = '-';
00858 break;
00859 #endif
00860 case 'n':
00861 #ifdef _HAVE_SANE_QUAD_
00862 if (flags & QUADINT)
00863 *va_arg(ap, quad_t *) = ret;
00864 else if (flags & LONGINT)
00865 #else
00866 if (flags & LONGINT)
00867 #endif
00868 *va_arg(ap, long *) = ret;
00869 else if (flags & SHORTINT)
00870 *va_arg(ap, short *) = (short)ret;
00871 else
00872 *va_arg(ap, int *) = (int)ret;
00873 continue;
00874 case 'O':
00875 flags |= LONGINT;
00876
00877 case 'o':
00878 #ifdef _HAVE_SANE_QUAD_
00879 if (flags & QUADINT)
00880 uqval = va_arg(ap, u_quad_t);
00881 else
00882 #endif
00883 ulval = UARG();
00884 base = 8;
00885 goto nosign;
00886 case 'p':
00887
00888
00889
00890
00891
00892
00893
00894 prec = (int)(sizeof(void*)*CHAR_BIT/4);
00895 #ifdef _HAVE_LLP64_
00896 uqval = (u_long)va_arg(ap, void *);
00897 flags = (flags) | QUADINT | HEXPREFIX;
00898 #else
00899 ulval = (u_long)va_arg(ap, void *);
00900 #ifdef _HAVE_SANE_QUAD_
00901 flags = (flags & ~QUADINT) | HEXPREFIX;
00902 #else
00903 flags = (flags) | HEXPREFIX;
00904 #endif
00905 #endif
00906 base = 16;
00907 xdigs = "0123456789abcdef";
00908 ch = 'x';
00909 goto nosign;
00910 case 's':
00911 if ((cp = va_arg(ap, char *)) == NULL)
00912 cp = "(null)";
00913 if (prec >= 0) {
00914
00915
00916
00917
00918
00919 const char *p = (char *)memchr(cp, 0, prec);
00920
00921 if (p != NULL && (p - cp) > prec)
00922 size = (int)(p - cp);
00923 else
00924 size = prec;
00925 }
00926 else {
00927 fieldsz = strlen(cp);
00928 goto long_len;
00929 }
00930 sign = '\0';
00931 break;
00932 case 'U':
00933 flags |= LONGINT;
00934
00935 case 'u':
00936 #ifdef _HAVE_SANE_QUAD_
00937 if (flags & QUADINT)
00938 uqval = va_arg(ap, u_quad_t);
00939 else
00940 #endif
00941 ulval = UARG();
00942 base = 10;
00943 goto nosign;
00944 case 'X':
00945 xdigs = "0123456789ABCDEF";
00946 goto hex;
00947 case 'x':
00948 xdigs = "0123456789abcdef";
00949 hex:
00950 #ifdef _HAVE_SANE_QUAD_
00951 if (flags & QUADINT)
00952 uqval = va_arg(ap, u_quad_t);
00953 else
00954 #endif
00955 ulval = UARG();
00956 base = 16;
00957
00958 if (flags & ALT &&
00959 #ifdef _HAVE_SANE_QUAD_
00960 (flags & QUADINT ? uqval != 0 : ulval != 0)
00961 #else
00962 ulval != 0
00963 #endif
00964 )
00965 flags |= HEXPREFIX;
00966
00967
00968 nosign: sign = '\0';
00969
00970
00971
00972
00973
00974 number: if ((dprec = prec) >= 0)
00975 flags &= ~ZEROPAD;
00976
00977
00978
00979
00980
00981
00982 #ifdef _HAVE_SANE_QUAD_
00983 if (flags & QUADINT) {
00984 if (uqval != 0 || prec != 0)
00985 cp = BSD__uqtoa(uqval, ebuf, base,
00986 flags & ALT, xdigs);
00987 } else
00988 #else
00989 #endif
00990 {
00991 if (ulval != 0 || prec != 0)
00992 cp = BSD__ultoa(ulval, ebuf, base,
00993 flags & ALT, xdigs);
00994 }
00995 size = (int)(ebuf - cp);
00996 break;
00997 default:
00998 if (ch == '\0')
00999 goto done;
01000
01001 cp = buf;
01002 *buf = ch;
01003 size = 1;
01004 sign = '\0';
01005 break;
01006 }
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 fieldsz = size;
01023 long_len:
01024 if (sign)
01025 fieldsz++;
01026 else if (flags & HEXPREFIX)
01027 fieldsz += 2;
01028 realsz = dprec > fieldsz ? dprec : fieldsz;
01029
01030
01031 if ((flags & (LADJUST|ZEROPAD)) == 0)
01032 PAD_L(width - realsz, blanks);
01033
01034
01035 if (sign) {
01036 PRINT(&sign, 1);
01037 } else if (flags & HEXPREFIX) {
01038 ox[0] = '0';
01039 ox[1] = ch;
01040 PRINT(ox, 2);
01041 }
01042
01043
01044 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
01045 PAD_L(width - realsz, zeroes);
01046
01047
01048 PAD_L(dprec - fieldsz, zeroes);
01049 if (sign)
01050 fieldsz--;
01051 else if (flags & HEXPREFIX)
01052 fieldsz -= 2;
01053
01054
01055 #ifdef FLOATING_POINT
01056 if ((flags & FPT) == 0) {
01057 PRINT(cp, fieldsz);
01058 } else {
01059 if (ch == 'a' || ch == 'A') {
01060 ox[0] = '0';
01061 ox[1] = ch + ('x' - 'a');
01062 PRINT(ox, 2);
01063 if (ndig > 1 || flags & ALT) {
01064 ox[2] = *cp++;
01065 ox[3] = '.';
01066 PRINT(ox+2, 2);
01067 PRINT(cp, ndig-1);
01068 } else
01069 PRINT(cp, 1);
01070 PRINT(expstr, expsize);
01071 }
01072 else if (ch >= 'f') {
01073 if (_double == 0) {
01074
01075 if (ndig <= 1 &&
01076 (flags & ALT) == 0) {
01077 PRINT("0", 1);
01078 } else {
01079 PRINT("0.", 2);
01080 PAD(ndig - 1, zeroes);
01081 }
01082 } else if (expt == 0 && ndig == 0 && (flags & ALT) == 0) {
01083 PRINT("0", 1);
01084 } else if (expt <= 0) {
01085 PRINT("0.", 2);
01086 PAD(-expt, zeroes);
01087 PRINT(cp, ndig);
01088 } else if (expt >= ndig) {
01089 PRINT(cp, ndig);
01090 PAD(expt - ndig, zeroes);
01091 if (flags & ALT)
01092 PRINT(".", 1);
01093 } else {
01094 PRINT(cp, expt);
01095 cp += expt;
01096 PRINT(".", 1);
01097 PRINT(cp, ndig-expt);
01098 }
01099 } else {
01100 if (ndig > 1 || flags & ALT) {
01101 ox[0] = *cp++;
01102 ox[1] = '.';
01103 PRINT(ox, 2);
01104 if (_double ) {
01105 PRINT(cp, ndig-1);
01106 } else
01107
01108 PAD(ndig - 1, zeroes);
01109 } else
01110 PRINT(cp, 1);
01111 PRINT(expstr, expsize);
01112 }
01113 }
01114 #else
01115 PRINT(cp, fieldsz);
01116 #endif
01117
01118 if (flags & LADJUST)
01119 PAD_L(width - realsz, blanks);
01120
01121
01122 ret += width > realsz ? width : realsz;
01123
01124 FLUSH();
01125 }
01126 done:
01127 FLUSH();
01128 error:
01129 return (__sferror(fp) ? EOF : ret);
01130
01131 }
01132
01133 #ifdef FLOATING_POINT
01134
01135 extern char *BSD__dtoa __P((double, int, int, int *, int *, char **));
01136 extern char *BSD__hdtoa(double, const char *, int, int *, int *, char **);
01137
01138 static char *
01139 cvt(value, ndigits, flags, sign, decpt, ch, length, buf)
01140 double value;
01141 int ndigits, flags, *decpt, ch, *length;
01142 char *sign, *buf;
01143 {
01144 int mode, dsgn;
01145 char *digits, *bp, *rve;
01146
01147 if (ch == 'f')
01148 mode = 3;
01149 else {
01150 mode = 2;
01151 }
01152 if (value < 0) {
01153 value = -value;
01154 *sign = '-';
01155 } else if (value == 0.0 && 1.0/value < 0) {
01156 *sign = '-';
01157 } else {
01158 *sign = '\000';
01159 }
01160 if (ch == 'a' || ch =='A') {
01161 digits = BSD__hdtoa(value,
01162 ch == 'a' ? "0123456789abcdef" : "0123456789ABCDEF",
01163 ndigits, decpt, &dsgn, &rve);
01164 }
01165 else {
01166 digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
01167 }
01168 memcpy(buf, digits, rve - digits);
01169 xfree(digits);
01170 rve = buf + (rve - digits);
01171 digits = buf;
01172 if (flags & ALT) {
01173 bp = digits + ndigits;
01174 if (ch == 'f') {
01175 if (*digits == '0' && value)
01176 *decpt = -ndigits + 1;
01177 bp += *decpt;
01178 }
01179 if (value == 0)
01180 rve = bp;
01181 while (rve < bp)
01182 *rve++ = '0';
01183 }
01184 *length = (int)(rve - digits);
01185 return (digits);
01186 }
01187
01188 static int
01189 exponent(p0, exp, fmtch)
01190 char *p0;
01191 int exp, fmtch;
01192 {
01193 register char *p, *t;
01194 char expbuf[MAXEXP];
01195
01196 p = p0;
01197 *p++ = fmtch;
01198 if (exp < 0) {
01199 exp = -exp;
01200 *p++ = '-';
01201 }
01202 else
01203 *p++ = '+';
01204 t = expbuf + MAXEXP;
01205 if (exp > 9) {
01206 do {
01207 *--t = to_char(exp % 10);
01208 } while ((exp /= 10) > 9);
01209 *--t = to_char(exp);
01210 for (; t < expbuf + MAXEXP; *p++ = *t++);
01211 }
01212 else {
01213 if (fmtch & 15) *p++ = '0';
01214 *p++ = to_char(exp);
01215 }
01216 return (int)(p - p0);
01217 }
01218 #endif
01219
01220 int
01221 ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
01222 {
01223 int ret;
01224 FILE f;
01225
01226 if ((int)n < 1)
01227 return (EOF);
01228 f._flags = __SWR | __SSTR;
01229 f._bf._base = f._p = (unsigned char *)str;
01230 f._bf._size = f._w = n - 1;
01231 f.vwrite = BSD__sfvwrite;
01232 ret = (int)BSD_vfprintf(&f, fmt, ap);
01233 *f._p = 0;
01234 return (ret);
01235 }
01236
01237 int
01238 ruby_snprintf(char *str, size_t n, char const *fmt, ...)
01239 {
01240 int ret;
01241 va_list ap;
01242 FILE f;
01243
01244 if ((int)n < 1)
01245 return (EOF);
01246
01247 va_start(ap, fmt);
01248 f._flags = __SWR | __SSTR;
01249 f._bf._base = f._p = (unsigned char *)str;
01250 f._bf._size = f._w = n - 1;
01251 f.vwrite = BSD__sfvwrite;
01252 ret = (int)BSD_vfprintf(&f, fmt, ap);
01253 *f._p = 0;
01254 va_end(ap);
01255 return (ret);
01256 }
01257