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 char *(*vextra)();
00187 } FILE;
00188
00189
00190 #define __SLBF 0x0001
00191 #define __SNBF 0x0002
00192 #define __SRD 0x0004
00193 #define __SWR 0x0008
00194
00195 #define __SRW 0x0010
00196 #define __SEOF 0x0020
00197 #define __SERR 0x0040
00198 #define __SMBF 0x0080
00199 #define __SAPP 0x0100
00200 #define __SSTR 0x0200
00201 #define __SOPT 0x0400
00202 #define __SNPT 0x0800
00203 #define __SOFF 0x1000
00204 #define __SMOD 0x2000
00205
00206
00207 #define EOF (-1)
00208
00209
00210 #define BSD__sfeof(p) (((p)->_flags & __SEOF) != 0)
00211 #define BSD__sferror(p) (((p)->_flags & __SERR) != 0)
00212 #define BSD__sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
00213 #define BSD__sfileno(p) ((p)->_file)
00214
00215 #undef feof
00216 #undef ferror
00217 #undef clearerr
00218 #define feof(p) BSD__sfeof(p)
00219 #define ferror(p) BSD__sferror(p)
00220 #define clearerr(p) BSD__sclearerr(p)
00221
00222 #ifndef _ANSI_SOURCE
00223 #define fileno(p) BSD__sfileno(p)
00224 #endif
00225
00226
00227
00228
00229
00230 struct __siov {
00231 const void *iov_base;
00232 size_t iov_len;
00233 };
00234 struct __suio {
00235 struct __siov *uio_iov;
00236 int uio_iovcnt;
00237 size_t uio_resid;
00238 };
00239
00240
00241
00242
00243
00244
00245
00246 static int
00247 BSD__sfvwrite(register FILE *fp, 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 #include <float.h>
00493
00494
00495 #ifndef MAXEXP
00496 # if DBL_MAX_10_EXP > -DBL_MIN_10_EXP
00497 # define MAXEXP (DBL_MAX_10_EXP)
00498 # else
00499 # define MAXEXP (-DBL_MIN_10_EXP)
00500 # endif
00501 #endif
00502
00503 #ifndef MAXFRACT
00504 # define MAXFRACT (MAXEXP*10/3)
00505 #endif
00506
00507 #define BUF (MAXEXP+MAXFRACT+1)
00508 #define DEFPREC 6
00509
00510 static char *cvt(double, int, int, char *, int *, int, int *, char *);
00511 static int exponent(char *, int, int);
00512
00513 #else
00514
00515 #define BUF 68
00516
00517 #endif
00518
00519
00520
00521
00522
00523 #define ALT 0x001
00524 #define HEXPREFIX 0x002
00525 #define LADJUST 0x004
00526 #define LONGDBL 0x008
00527 #define LONGINT 0x010
00528
00529 #ifdef _HAVE_SANE_QUAD_
00530 #define QUADINT 0x020
00531 #endif
00532
00533 #define SHORTINT 0x040
00534 #define ZEROPAD 0x080
00535 #define FPT 0x100
00536 static ssize_t
00537 BSD_vfprintf(FILE *fp, const char *fmt0, va_list ap)
00538 {
00539 register const char *fmt;
00540 register int ch;
00541 register int n;
00542 register const char *cp;
00543 register struct __siov *iovp;
00544 register int flags;
00545 ssize_t ret;
00546 int width;
00547 int prec;
00548 char sign;
00549 #ifdef FLOATING_POINT
00550 char softsign;
00551 double _double = 0;
00552 int expt;
00553 int expsize = 0;
00554 int ndig = 0;
00555 int fprec = 0;
00556 char expstr[7];
00557 #endif
00558 u_long UNINITIALIZED_VAR(ulval);
00559 #ifdef _HAVE_SANE_QUAD_
00560 u_quad_t UNINITIALIZED_VAR(uqval);
00561 #endif
00562 int base;
00563 int dprec;
00564 long fieldsz;
00565 long realsz;
00566 int size;
00567 const char *xdigs = 0;
00568 #define NIOV 8
00569 struct __suio uio;
00570 struct __siov iov[NIOV];
00571 char buf[BUF];
00572 char ox[4];
00573 char *const ebuf = buf + sizeof(buf);
00574 #if SIZEOF_LONG > SIZEOF_INT
00575 long ln;
00576 #endif
00577
00578
00579
00580
00581
00582
00583 #define PADSIZE 16
00584 static const char blanks[PADSIZE] =
00585 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
00586 static const char zeroes[PADSIZE] =
00587 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
00588
00589
00590
00591
00592 #define PRINT(ptr, len) { \
00593 iovp->iov_base = (ptr); \
00594 iovp->iov_len = (len); \
00595 uio.uio_resid += (len); \
00596 iovp++; \
00597 if (++uio.uio_iovcnt >= NIOV) { \
00598 if (BSD__sprint(fp, &uio)) \
00599 goto error; \
00600 iovp = iov; \
00601 } \
00602 }
00603 #define PAD(howmany, with) { \
00604 if ((n = (howmany)) > 0) { \
00605 while (n > PADSIZE) { \
00606 PRINT((with), PADSIZE); \
00607 n -= PADSIZE; \
00608 } \
00609 PRINT((with), n); \
00610 } \
00611 }
00612 #if SIZEOF_LONG > SIZEOF_INT
00613
00614 #define PAD_L(howmany, with) { \
00615 ln = (howmany); \
00616 if ((long)((int)ln) != ln) { \
00617 errno = ENOMEM; \
00618 goto error; \
00619 } \
00620 if (ln > 0) PAD((int)ln, (with)); \
00621 }
00622 #else
00623 #define PAD_L(howmany, with) PAD((howmany), (with))
00624 #endif
00625 #define FLUSH() { \
00626 if (uio.uio_resid && BSD__sprint(fp, &uio)) \
00627 goto error; \
00628 uio.uio_iovcnt = 0; \
00629 iovp = iov; \
00630 }
00631
00632
00633
00634
00635
00636 #define SARG() \
00637 (flags&LONGINT ? va_arg(ap, long) : \
00638 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
00639 (long)va_arg(ap, int))
00640 #define UARG() \
00641 (flags&LONGINT ? va_arg(ap, u_long) : \
00642 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
00643 (u_long)va_arg(ap, u_int))
00644
00645
00646 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
00647 fp->_file >= 0)
00648 return (BSD__sbprintf(fp, fmt0, ap));
00649
00650 fmt = fmt0;
00651 uio.uio_iov = iovp = iov;
00652 uio.uio_resid = 0;
00653 uio.uio_iovcnt = 0;
00654 ret = 0;
00655 xdigs = 0;
00656
00657
00658
00659
00660 for (;;) {
00661 size_t nc;
00662 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
00663 ;
00664 if ((nc = fmt - cp) != 0) {
00665 PRINT(cp, nc);
00666 ret += nc;
00667 }
00668 if (ch == '\0')
00669 goto done;
00670 fmt++;
00671
00672 flags = 0;
00673 dprec = 0;
00674 width = 0;
00675 prec = -1;
00676 sign = '\0';
00677
00678 rflag: ch = *fmt++;
00679 reswitch: switch (ch) {
00680 case ' ':
00681
00682
00683
00684
00685
00686 if (!sign)
00687 sign = ' ';
00688 goto rflag;
00689 case '#':
00690 flags |= ALT;
00691 goto rflag;
00692 case '*':
00693
00694
00695
00696
00697
00698
00699 if ((width = va_arg(ap, int)) >= 0)
00700 goto rflag;
00701 width = -width;
00702
00703 case '-':
00704 flags |= LADJUST;
00705 goto rflag;
00706 case '+':
00707 sign = '+';
00708 goto rflag;
00709 case '.':
00710 if ((ch = *fmt++) == '*') {
00711 n = va_arg(ap, int);
00712 prec = n < 0 ? -1 : n;
00713 goto rflag;
00714 }
00715 n = 0;
00716 while (is_digit(ch)) {
00717 n = 10 * n + to_digit(ch);
00718 ch = *fmt++;
00719 }
00720 prec = n < 0 ? -1 : n;
00721 goto reswitch;
00722 case '0':
00723
00724
00725
00726
00727
00728 flags |= ZEROPAD;
00729 goto rflag;
00730 case '1': case '2': case '3': case '4':
00731 case '5': case '6': case '7': case '8': case '9':
00732 n = 0;
00733 do {
00734 n = 10 * n + to_digit(ch);
00735 ch = *fmt++;
00736 } while (is_digit(ch));
00737 width = n;
00738 goto reswitch;
00739 #ifdef FLOATING_POINT
00740 case 'L':
00741 flags |= LONGDBL;
00742 goto rflag;
00743 #endif
00744 case 'h':
00745 flags |= SHORTINT;
00746 goto rflag;
00747 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG
00748 case 't':
00749 #endif
00750 #if SIZEOF_SIZE_T == SIZEOF_LONG
00751 case 'z':
00752 #endif
00753 case 'l':
00754 #ifdef _HAVE_SANE_QUAD_
00755 if (*fmt == 'l') {
00756 fmt++;
00757 flags |= QUADINT;
00758 } else {
00759 flags |= LONGINT;
00760 }
00761 #else
00762 flags |= LONGINT;
00763 #endif
00764 goto rflag;
00765 #ifdef _HAVE_SANE_QUAD_
00766 #if SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
00767 case 't':
00768 #endif
00769 #if SIZEOF_SIZE_T == SIZEOF_LONG_LONG
00770 case 'z':
00771 #endif
00772 case 'q':
00773 flags |= QUADINT;
00774 goto rflag;
00775 #endif
00776 #ifdef _WIN32
00777 case 'I':
00778 if (*fmt == '3' && *(fmt + 1) == '2') {
00779 fmt += 2;
00780 flags |= LONGINT;
00781 }
00782 #ifdef _HAVE_SANE_QUAD_
00783 else if (*fmt == '6' && *(fmt + 1) == '4') {
00784 fmt += 2;
00785 flags |= QUADINT;
00786 }
00787 #endif
00788 else
00789 #if defined(_HAVE_SANE_QUAD_) && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
00790 flags |= QUADINT;
00791 #else
00792 flags |= LONGINT;
00793 #endif
00794 goto rflag;
00795 #endif
00796 case 'c':
00797 cp = buf;
00798 *buf = (char)va_arg(ap, int);
00799 size = 1;
00800 sign = '\0';
00801 break;
00802 case 'i':
00803 #ifdef _HAVE_SANE_QUAD_
00804 # define INTPTR_MASK (QUADINT|LONGINT|SHORTINT)
00805 #else
00806 # define INTPTR_MASK (LONGINT|SHORTINT)
00807 #endif
00808 #if defined _HAVE_SANE_QUAD_ && SIZEOF_VOIDP == SIZEOF_LONG_LONG
00809 # define INTPTR_FLAG QUADINT
00810 #elif SIZEOF_VOIDP == SIZEOF_LONG
00811 # define INTPTR_FLAG LONGINT
00812 #else
00813 # define INTPTR_FLAG 0
00814 #endif
00815 if (fp->vextra && (flags & INTPTR_MASK) == INTPTR_FLAG) {
00816 FLUSH();
00817 #if defined _HAVE_SANE_QUAD_ && SIZEOF_VOIDP == SIZEOF_LONG_LONG
00818 uqval = va_arg(ap, u_quad_t);
00819 cp = (*fp->vextra)(fp, sizeof(uqval), &uqval, &fieldsz, sign);
00820 #else
00821 ulval = va_arg(ap, u_long);
00822 cp = (*fp->vextra)(fp, sizeof(ulval), &ulval, &fieldsz, sign);
00823 #endif
00824 sign = '\0';
00825 if (!cp) goto error;
00826 if (prec < 0) goto long_len;
00827 size = fieldsz < prec ? (int)fieldsz : prec;
00828 break;
00829 }
00830 goto decimal;
00831 case 'D':
00832 flags |= LONGINT;
00833
00834 case 'd':
00835 decimal:
00836 #ifdef _HAVE_SANE_QUAD_
00837 if (flags & QUADINT) {
00838 uqval = va_arg(ap, quad_t);
00839 if ((quad_t)uqval < 0) {
00840 uqval = -(quad_t)uqval;
00841 sign = '-';
00842 }
00843 } else
00844 #endif
00845 {
00846 ulval = SARG();
00847 if ((long)ulval < 0) {
00848 ulval = (u_long)(-(long)ulval);
00849 sign = '-';
00850 }
00851 }
00852 base = 10;
00853 goto number;
00854 #ifdef FLOATING_POINT
00855 case 'a':
00856 case 'A':
00857 if (prec > 0) {
00858 flags |= ALT;
00859 prec++;
00860 fprec = prec;
00861 }
00862 goto fp_begin;
00863 case 'e':
00864 case 'E':
00865 if (prec != 0)
00866 flags |= ALT;
00867 prec = (prec == -1) ?
00868 DEFPREC + 1 : (fprec = prec + 1);
00869
00870 goto fp_begin;
00871 case 'f':
00872 if (prec != 0)
00873 flags |= ALT;
00874 case 'g':
00875 case 'G':
00876 if (prec == -1)
00877 prec = DEFPREC;
00878 else
00879 fprec = prec;
00880 fp_begin: _double = va_arg(ap, double);
00881
00882 if (isinf(_double)) {
00883 if (_double < 0)
00884 sign = '-';
00885 cp = "Inf";
00886 size = 3;
00887 break;
00888 }
00889 if (isnan(_double)) {
00890 cp = "NaN";
00891 size = 3;
00892 break;
00893 }
00894 flags |= FPT;
00895 cp = cvt(_double, (prec < MAXFRACT ? prec : MAXFRACT), flags, &softsign,
00896 &expt, ch, &ndig, buf);
00897 if (ch == 'g' || ch == 'G') {
00898 if (expt <= -4 || (expt > prec && expt > 1))
00899 ch = (ch == 'g') ? 'e' : 'E';
00900 else
00901 ch = 'g';
00902 }
00903 if (ch == 'a' || ch == 'A') {
00904 flags |= HEXPREFIX;
00905 --expt;
00906 expsize = exponent(expstr, expt, ch + 'p' - 'a');
00907 ch += 'x' - 'a';
00908 size = expsize + ndig;
00909 if (ndig > 1 || flags & ALT)
00910 ++size;
00911 }
00912 else if (ch <= 'e') {
00913 --expt;
00914 expsize = exponent(expstr, expt, ch);
00915 size = expsize + ndig;
00916 if (ndig > 1 || flags & ALT)
00917 ++fprec, ++size;
00918 } else if (ch == 'f') {
00919 if (expt > 0) {
00920 size = expt;
00921 if (prec || flags & ALT)
00922 size += prec + 1;
00923 } else if (!prec) {
00924 size = 1;
00925 if (flags & ALT)
00926 size += 1;
00927 } else
00928 size = prec + 2;
00929 } else if (expt >= ndig) {
00930 size = expt;
00931 if (flags & ALT)
00932 ++size;
00933 } else
00934 size = ndig + (expt > 0 ?
00935 1 : 2 - expt);
00936
00937 if (softsign)
00938 sign = '-';
00939 break;
00940 #endif
00941 case 'n':
00942 #ifdef _HAVE_SANE_QUAD_
00943 if (flags & QUADINT)
00944 *va_arg(ap, quad_t *) = ret;
00945 else if (flags & LONGINT)
00946 #else
00947 if (flags & LONGINT)
00948 #endif
00949 *va_arg(ap, long *) = ret;
00950 else if (flags & SHORTINT)
00951 *va_arg(ap, short *) = (short)ret;
00952 else
00953 *va_arg(ap, int *) = (int)ret;
00954 continue;
00955 case 'O':
00956 flags |= LONGINT;
00957
00958 case 'o':
00959 #ifdef _HAVE_SANE_QUAD_
00960 if (flags & QUADINT)
00961 uqval = va_arg(ap, u_quad_t);
00962 else
00963 #endif
00964 ulval = UARG();
00965 base = 8;
00966 goto nosign;
00967 case 'p':
00968
00969
00970
00971
00972
00973
00974
00975 prec = (int)(sizeof(void*)*CHAR_BIT/4);
00976 #ifdef _HAVE_LLP64_
00977 uqval = (u_quad_t)va_arg(ap, void *);
00978 flags = (flags) | QUADINT | HEXPREFIX;
00979 #else
00980 ulval = (u_long)va_arg(ap, void *);
00981 #ifdef _HAVE_SANE_QUAD_
00982 flags = (flags & ~QUADINT) | HEXPREFIX;
00983 #else
00984 flags = (flags) | HEXPREFIX;
00985 #endif
00986 #endif
00987 base = 16;
00988 xdigs = "0123456789abcdef";
00989 ch = 'x';
00990 goto nosign;
00991 case 's':
00992 if ((cp = va_arg(ap, char *)) == NULL)
00993 cp = "(null)";
00994 if (prec >= 0) {
00995
00996
00997
00998
00999
01000 const char *p = (char *)memchr(cp, 0, prec);
01001
01002 if (p != NULL && (p - cp) < prec)
01003 size = (int)(p - cp);
01004 else
01005 size = prec;
01006 }
01007 else {
01008 fieldsz = strlen(cp);
01009 goto long_len;
01010 }
01011 sign = '\0';
01012 break;
01013 case 'U':
01014 flags |= LONGINT;
01015
01016 case 'u':
01017 #ifdef _HAVE_SANE_QUAD_
01018 if (flags & QUADINT)
01019 uqval = va_arg(ap, u_quad_t);
01020 else
01021 #endif
01022 ulval = UARG();
01023 base = 10;
01024 goto nosign;
01025 case 'X':
01026 xdigs = "0123456789ABCDEF";
01027 goto hex;
01028 case 'x':
01029 xdigs = "0123456789abcdef";
01030 hex:
01031 #ifdef _HAVE_SANE_QUAD_
01032 if (flags & QUADINT)
01033 uqval = va_arg(ap, u_quad_t);
01034 else
01035 #endif
01036 ulval = UARG();
01037 base = 16;
01038
01039 if (flags & ALT &&
01040 #ifdef _HAVE_SANE_QUAD_
01041 (flags & QUADINT ? uqval != 0 : ulval != 0)
01042 #else
01043 ulval != 0
01044 #endif
01045 )
01046 flags |= HEXPREFIX;
01047
01048
01049 nosign: sign = '\0';
01050
01051
01052
01053
01054
01055 number: if ((dprec = prec) >= 0)
01056 flags &= ~ZEROPAD;
01057
01058
01059
01060
01061
01062
01063 #ifdef _HAVE_SANE_QUAD_
01064 if (flags & QUADINT) {
01065 if (uqval != 0 || prec != 0)
01066 cp = BSD__uqtoa(uqval, ebuf, base,
01067 flags & ALT, xdigs);
01068 } else
01069 #else
01070 #endif
01071 {
01072 if (ulval != 0 || prec != 0)
01073 cp = BSD__ultoa(ulval, ebuf, base,
01074 flags & ALT, xdigs);
01075 }
01076 size = (int)(ebuf - cp);
01077 break;
01078 default:
01079 if (ch == '\0')
01080 goto done;
01081
01082 cp = buf;
01083 *buf = ch;
01084 size = 1;
01085 sign = '\0';
01086 break;
01087 }
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 fieldsz = size;
01104 long_len:
01105 if (sign)
01106 fieldsz++;
01107 if (flags & HEXPREFIX)
01108 fieldsz += 2;
01109 realsz = dprec > fieldsz ? dprec : fieldsz;
01110
01111
01112 if ((flags & (LADJUST|ZEROPAD)) == 0)
01113 PAD_L(width - realsz, blanks);
01114
01115
01116 if (sign) {
01117 PRINT(&sign, 1);
01118 }
01119 if (flags & HEXPREFIX) {
01120 ox[0] = '0';
01121 ox[1] = ch;
01122 PRINT(ox, 2);
01123 }
01124
01125
01126 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
01127 PAD_L(width - realsz, zeroes);
01128
01129
01130 PAD_L(dprec - fieldsz, zeroes);
01131 if (sign)
01132 fieldsz--;
01133 if (flags & HEXPREFIX)
01134 fieldsz -= 2;
01135
01136
01137 #ifdef FLOATING_POINT
01138 if ((flags & FPT) == 0) {
01139 PRINT(cp, fieldsz);
01140 } else {
01141 if (flags & HEXPREFIX) {
01142 if (ndig > 1 || flags & ALT) {
01143 ox[2] = *cp++;
01144 ox[3] = '.';
01145 PRINT(ox+2, 2);
01146 if (ndig > 0) PRINT(cp, ndig-1);
01147 } else
01148 PRINT(cp, 1);
01149 PAD(fprec-ndig, zeroes);
01150 PRINT(expstr, expsize);
01151 }
01152 else if (ch >= 'f') {
01153 if (_double == 0) {
01154
01155 if (ndig <= 1 &&
01156 (flags & ALT) == 0) {
01157 PRINT("0", 1);
01158 } else {
01159 PRINT("0.", 2);
01160 PAD((ndig >= fprec ? ndig - 1 : fprec - (ch != 'f')),
01161 zeroes);
01162 }
01163 } else if (expt == 0 && ndig == 0 && (flags & ALT) == 0) {
01164 PRINT("0", 1);
01165 } else if (expt <= 0) {
01166 PRINT("0.", 2);
01167 PAD(-expt, zeroes);
01168 PRINT(cp, ndig);
01169 if (flags & ALT)
01170 PAD(fprec - ndig + (ch == 'f' ? expt : 0), zeroes);
01171 } else if (expt >= ndig) {
01172 PRINT(cp, ndig);
01173 PAD(expt - ndig, zeroes);
01174 if (flags & ALT)
01175 PRINT(".", 1);
01176 } else {
01177 PRINT(cp, expt);
01178 cp += expt;
01179 PRINT(".", 1);
01180 PRINT(cp, ndig-expt);
01181 if (flags & ALT)
01182 PAD(fprec - ndig + (ch == 'f' ? expt : 0), zeroes);
01183 }
01184 } else {
01185 if (ndig > 1 || flags & ALT) {
01186 ox[0] = *cp++;
01187 ox[1] = '.';
01188 PRINT(ox, 2);
01189 if (_double ) {
01190 PRINT(cp, ndig-1);
01191 } else
01192
01193 PAD(ndig - 1, zeroes);
01194 if (flags & ALT) PAD(fprec - ndig - 1, zeroes);
01195 } else
01196 PRINT(cp, 1);
01197 PRINT(expstr, expsize);
01198 }
01199 }
01200 #else
01201 PRINT(cp, fieldsz);
01202 #endif
01203
01204 if (flags & LADJUST)
01205 PAD_L(width - realsz, blanks);
01206
01207
01208 ret += width > realsz ? width : realsz;
01209
01210 FLUSH();
01211 }
01212 done:
01213 FLUSH();
01214 error:
01215 return (BSD__sferror(fp) ? EOF : ret);
01216
01217 }
01218
01219 #ifdef FLOATING_POINT
01220
01221 extern char *BSD__dtoa(double, int, int, int *, int *, char **);
01222 extern char *BSD__hdtoa(double, const char *, int, int *, int *, char **);
01223
01224 static char *
01225 cvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch, int *length, char *buf)
01226 {
01227 int mode, dsgn;
01228 char *digits, *bp, *rve;
01229
01230 if (ch == 'f')
01231 mode = 3;
01232 else {
01233 mode = 2;
01234 }
01235 if (value < 0) {
01236 value = -value;
01237 *sign = '-';
01238 } else if (value == 0.0 && 1.0/value < 0) {
01239 *sign = '-';
01240 } else {
01241 *sign = '\000';
01242 }
01243 if (ch == 'a' || ch =='A') {
01244 digits = BSD__hdtoa(value,
01245 ch == 'a' ? "0123456789abcdef" : "0123456789ABCDEF",
01246 ndigits, decpt, &dsgn, &rve);
01247 }
01248 else {
01249 digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
01250 }
01251 buf[0] = 0;
01252 memcpy(buf, digits, rve - digits);
01253 xfree(digits);
01254 rve = buf + (rve - digits);
01255 digits = buf;
01256 if (flags & ALT) {
01257 bp = digits + ndigits;
01258 if (ch == 'f') {
01259 if (*digits == '0' && value)
01260 *decpt = -ndigits + 1;
01261 bp += *decpt;
01262 }
01263 while (rve < bp)
01264 *rve++ = '0';
01265 }
01266 *length = (int)(rve - digits);
01267 return (digits);
01268 }
01269
01270 static int
01271 exponent(char *p0, int exp, int fmtch)
01272 {
01273 register char *p, *t;
01274 char expbuf[2 + (MAXEXP < 1000 ? 3 : MAXEXP < 10000 ? 4 : 5)];
01275
01276 p = p0;
01277 *p++ = fmtch;
01278 if (exp < 0) {
01279 exp = -exp;
01280 *p++ = '-';
01281 }
01282 else
01283 *p++ = '+';
01284 t = expbuf + sizeof(expbuf);
01285 if (exp > 9) {
01286 do {
01287 *--t = to_char(exp % 10);
01288 } while ((exp /= 10) > 9);
01289 *--t = to_char(exp);
01290 for (; t < expbuf + sizeof(expbuf); *p++ = *t++);
01291 }
01292 else {
01293 if (fmtch & 15) *p++ = '0';
01294 *p++ = to_char(exp);
01295 }
01296 return (int)(p - p0);
01297 }
01298 #endif
01299
01300 int
01301 ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
01302 {
01303 int ret;
01304 FILE f;
01305
01306 if ((int)n < 1)
01307 return (EOF);
01308 f._flags = __SWR | __SSTR;
01309 f._bf._base = f._p = (unsigned char *)str;
01310 f._bf._size = f._w = n - 1;
01311 f.vwrite = BSD__sfvwrite;
01312 f.vextra = 0;
01313 ret = (int)BSD_vfprintf(&f, fmt, ap);
01314 *f._p = 0;
01315 return (ret);
01316 }
01317
01318 int
01319 ruby_snprintf(char *str, size_t n, char const *fmt, ...)
01320 {
01321 int ret;
01322 va_list ap;
01323 FILE f;
01324
01325 if ((int)n < 1)
01326 return (EOF);
01327
01328 va_start(ap, fmt);
01329 f._flags = __SWR | __SSTR;
01330 f._bf._base = f._p = (unsigned char *)str;
01331 f._bf._size = f._w = n - 1;
01332 f.vwrite = BSD__sfvwrite;
01333 f.vextra = 0;
01334 ret = (int)BSD_vfprintf(&f, fmt, ap);
01335 *f._p = 0;
01336 va_end(ap);
01337 return (ret);
01338 }
01339