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