2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
37 * paragraph 3 above is now null and void.
41 * fjc 7-31-97 Modified by Mib Software to be a standalone snprintf.c module.
42 * http://www.mibsoftware.com
43 * Mib Software does not warrant this software any differently than the
44 * University of California, Berkeley as described above. All warranties
45 * are disclaimed. Use this software at your own risk.
47 * All code referencing FILE * functions was eliminated, since it could
48 * never be called. All header files and necessary files are collapsed
49 * into one file, internal functions are declared static. This should
50 * allow inclusion into libraries with less chance of namespace collisions.
52 * snprintf should be the only externally visible item.
54 * As of 7-31-97 FLOATING_POINT is NOT provided. The code is somewhat
55 * non-portable, so it is disabled.
58 /* Define FLOATING_POINT to get floating point. */
60 #define FLOATING_POINT
63 #include <sys/types.h>
64 #define u_long unsigned long
65 #define u_short unsigned short
66 #define u_int unsigned int
68 #if !defined(HAVE_STDARG_PROTOTYPES)
70 #define HAVE_STDARG_PROTOTYPES 1
75 #if defined(HAVE_STDARG_PROTOTYPES)
88 #define _BSD_VA_LIST_ va_list
98 /* assuming 32bit(2's compliment) long */
99 # define LONG_MAX 2147483647
104 #if defined(__hpux) && !defined(__GNUC__) && !defined(__STDC__)
111 #endif /* People who don't like const sys_error */
114 #if defined(__hpux) && !defined(__GNUC__) || defined(__DECC)
118 #if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__)
127 * NB: to fit things in six character monocase externals, the stdio
128 * code uses the prefix `__s' for stdio objects, typically followed
129 * by a three-character attempt at a mnemonic.
134 unsigned char *_base
;
140 * stdio state variables.
142 * The following always hold:
144 * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
145 * _lbfsize is -_bf._size, else _lbfsize is 0
146 * if _flags&__SRD, _w is 0
147 * if _flags&__SWR, _r is 0
149 * This ensures that the getc and putc macros (or inline functions) never
150 * try to write or read from a file that is in `read' or `write' mode.
151 * (Moreover, they can, and do, automatically switch from read mode to
152 * write mode, and back, on "r+" and "w+" files.)
154 * _lbfsize is used only to make the inline line-buffered output stream
155 * code as compact as possible.
157 * _ub, _up, and _ur are used when ungetc() pushes back more characters
158 * than fit in the current _bf, or when ungetc() pushes back a character
159 * that does not match the previous one in _bf. When this happens,
160 * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
161 * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
163 * NB: see WARNING above before changing the layout of this structure!
165 typedef struct __sFILE
{
166 unsigned char *_p
; /* current position in (some) buffer */
168 size_t _r
; /* read space left for getc() */
170 size_t _w
; /* write space left for putc() */
171 short _flags
; /* flags, below; this FILE is free if 0 */
172 short _file
; /* fileno, if Unix descriptor, else -1 */
173 struct __sbuf _bf
; /* the buffer (at least 1 byte, if !NULL) */
174 size_t _lbfsize
; /* 0 or -_bf._size, for inline putc */
175 int (*vwrite
)(/* struct __sFILE*, struct __suio * */);
179 #define __SLBF 0x0001 /* line buffered */
180 #define __SNBF 0x0002 /* unbuffered */
181 #define __SRD 0x0004 /* OK to read */
182 #define __SWR 0x0008 /* OK to write */
183 /* RD and WR are never simultaneously asserted */
184 #define __SRW 0x0010 /* open for reading & writing */
185 #define __SEOF 0x0020 /* found EOF */
186 #define __SERR 0x0040 /* found error */
187 #define __SMBF 0x0080 /* _buf is from malloc */
188 #define __SAPP 0x0100 /* fdopen()ed in append mode */
189 #define __SSTR 0x0200 /* this is an sprintf/snprintf string */
190 #define __SOPT 0x0400 /* do fseek() optimisation */
191 #define __SNPT 0x0800 /* do not do fseek() optimisation */
192 #define __SOFF 0x1000 /* set iff _offset is in fact correct */
193 #define __SMOD 0x2000 /* true => fgetln modified _p text */
199 #define __sfeof(p) (((p)->_flags & __SEOF) != 0)
200 #define __sferror(p) (((p)->_flags & __SERR) != 0)
201 #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
202 #define __sfileno(p) ((p)->_file)
207 #define feof(p) __sfeof(p)
208 #define ferror(p) __sferror(p)
209 #define clearerr(p) __sclearerr(p)
212 #define fileno(p) __sfileno(p)
217 * I/O descriptors for __sfvwrite().
220 const void *iov_base
;
224 struct __siov
*uio_iov
;
229 #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_SNPRINTF)
231 * Write some memory regions. Return zero on success, EOF on error.
233 * This routine is large and unsightly, but most of the ugliness due
234 * to the three different kinds of output buffering is handled here.
236 static int BSD__sfvwrite(fp
, uio
)
238 register struct __suio
*uio
;
242 register struct __siov
*iov
;
245 if ((len
= uio
->uio_resid
) == 0)
248 #define MIN(a, b) ((a) < (b) ? (a) : (b))
250 #define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
256 #define GETIOV(extra_work) \
260 len = iov->iov_len; \
263 if (fp
->_flags
& __SNBF
) {
264 /* fjc 7-31-97 Will never happen. We are working with
267 } else if ((fp
->_flags
& __SLBF
) == 0) {
269 * Fully buffered: fill partially full buffer, if any,
270 * and then flush. If there is no partial buffer, write
271 * one _bf._size byte chunk directly (without copying).
273 * String output is a special case: write as many bytes
274 * as fit, but pretend we wrote everything. This makes
275 * snprintf() return the number of bytes needed, rather
276 * than the number used, and avoids its write function
277 * (so that the write function can be invalid).
282 if (fp
->_flags
& __SSTR
) {
285 COPY(w
); /* copy MIN(fp->_w,len), */
288 w
= len
; /* but pretend copied all */
290 /* fjc 7-31-97 Will never happen. We are working with
296 } while ((uio
->uio_resid
-= w
) != 0);
298 /* fjc 7-31-97 Will never happen. We are working with
307 * Actual printf innards.
309 * This code is large and complicated...
313 * Flush out all the vectors defined by the given uio,
314 * then reset it so that it can be reused.
317 BSD__sprint(FILE *fp
, register struct __suio
*uio
)
321 if (uio
->uio_resid
== 0) {
325 err
= (*fp
->vwrite
)(fp
, uio
);
333 * Helper function for `fprintf to unbuffered unix file': creates a
334 * temporary buffer. We only work on write-only files; this avoids
335 * worries about ungetc buffers and so forth.
338 BSD__sbprintf(register FILE *fp
, const char *fmt
, va_list ap
)
340 /* We don't support files. */
346 * Macros for converting digits to letters and vice versa
348 #define to_digit(c) ((c) - '0')
349 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
350 #define to_char(n) ((n) + '0')
352 #ifdef _HAVE_SANE_QUAD_
354 * Convert an unsigned long long to ASCII for printf purposes, returning
355 * a pointer to the first character of the string representation.
356 * Octal numbers can be forced to have a leading zero; hex numbers
357 * use the given digits.
360 BSD__uqtoa(register u_quad_t val
, char *endp
, int base
, int octzero
, const char *xdigs
)
362 register char *cp
= endp
;
366 * Handle the three cases separately, in the hope of getting
367 * better/faster code.
371 if (val
< 10) { /* many numbers are 1 digit */
372 *--cp
= to_char(val
);
376 * On many machines, unsigned arithmetic is harder than
377 * signed arithmetic, so we do at most one unsigned mod and
378 * divide; this is sufficient to reduce the range of
379 * the incoming value to where signed arithmetic works.
381 if (val
> LLONG_MAX
) {
382 *--cp
= to_char(val
% 10);
387 *--cp
= to_char(sval
% 10);
394 *--cp
= to_char(val
& 7);
397 if (octzero
&& *cp
!= '0')
403 *--cp
= xdigs
[val
& 15];
412 break; /* fjc 7-31-97. Don't reference abort() here */
416 #endif /* _HAVE_SANE_QUAD_ */
419 * Convert an unsigned long to ASCII for printf purposes, returning
420 * a pointer to the first character of the string representation.
421 * Octal numbers can be forced to have a leading zero; hex numbers
422 * use the given digits.
425 BSD__ultoa(register u_long val
, char *endp
, int base
, int octzero
, const char *xdigs
)
427 register char *cp
= endp
;
431 * Handle the three cases separately, in the hope of getting
432 * better/faster code.
436 if (val
< 10) { /* many numbers are 1 digit */
437 *--cp
= to_char(val
);
441 * On many machines, unsigned arithmetic is harder than
442 * signed arithmetic, so we do at most one unsigned mod and
443 * divide; this is sufficient to reduce the range of
444 * the incoming value to where signed arithmetic works.
446 if (val
> LONG_MAX
) {
447 *--cp
= to_char(val
% 10);
452 *--cp
= to_char(sval
% 10);
459 *--cp
= to_char(val
& 7);
462 if (octzero
&& *cp
!= '0')
468 *--cp
= xdigs
[val
& 15];
477 break; /* fjc 7-31-97. Don't reference abort() here */
482 #ifdef FLOATING_POINT
484 /* #include "floatio.h" */
494 #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
497 static char *cvt
__P((double, int, int, char *, int *, int, int *));
498 static int exponent
__P((char *, int, int));
500 #else /* no FLOATING_POINT */
504 #endif /* FLOATING_POINT */
508 * Flags used during conversion.
510 #define ALT 0x001 /* alternate form */
511 #define HEXPREFIX 0x002 /* add 0x or 0X prefix */
512 #define LADJUST 0x004 /* left adjustment */
513 #define LONGDBL 0x008 /* long double; unimplemented */
514 #define LONGINT 0x010 /* long integer */
516 #ifdef _HAVE_SANE_QUAD_
517 #define QUADINT 0x020 /* quad integer */
518 #endif /* _HAVE_SANE_QUAD_ */
520 #define SHORTINT 0x040 /* short integer */
521 #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
522 #define FPT 0x100 /* Floating point number */
524 BSD_vfprintf(FILE *fp
, const char *fmt0
, va_list ap
)
526 register const char *fmt
; /* format string */
527 register int ch
; /* character from fmt */
528 register int n
; /* handy integer (short term usage) */
529 register const char *cp
;/* handy char pointer (short term usage) */
530 register struct __siov
*iovp
;/* for PRINT macro */
531 register int flags
; /* flags as above */
532 int ret
; /* return value accumulator */
533 int width
; /* width from format (%8d), or 0 */
534 int prec
; /* precision from format (%.3d), or -1 */
535 char sign
; /* sign prefix (' ', '+', '-', or \0) */
536 #ifdef FLOATING_POINT
537 char softsign
; /* temporary negative sign for floats */
538 double _double
; /* double precision arguments %[eEfgG] */
539 int expt
; /* integer value of exponent */
540 int expsize
; /* character count for expstr */
541 int ndig
; /* actual number of digits returned by cvt */
542 char expstr
[7]; /* buffer for exponent string */
544 u_long ulval
; /* integer arguments %[diouxX] */
545 #ifdef _HAVE_SANE_QUAD_
546 u_quad_t uqval
; /* %q integers */
547 #endif /* _HAVE_SANE_QUAD_ */
548 int base
; /* base for [diouxX] conversion */
549 int dprec
; /* a copy of prec if [diouxX], 0 otherwise */
550 int fieldsz
; /* field size expanded by sign, etc */
551 int realsz
; /* field size expanded by dprec */
552 int size
; /* size of converted field or string */
553 const char *xdigs
= 0; /* digits for [xX] conversion */
555 struct __suio uio
; /* output information: summary */
556 struct __siov iov
[NIOV
];/* ... and individual io vectors */
557 char buf
[BUF
]; /* space for %c, %[diouxX], %[eEfgG] */
558 char ox
[2]; /* space for 0x hex-prefix */
559 char *const ebuf
= buf
+ sizeof(buf
);
562 * Choose PADSIZE to trade efficiency vs. size. If larger printf
563 * fields occur frequently, increase PADSIZE and make the initializers
566 #define PADSIZE 16 /* pad chunk size */
567 static const char blanks
[PADSIZE
] =
568 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
569 static const char zeroes
[PADSIZE
] =
570 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
573 * BEWARE, these `goto error' on error, and PAD uses `n'.
575 #define PRINT(ptr, len) { \
576 iovp->iov_base = (ptr); \
577 iovp->iov_len = (len); \
578 uio.uio_resid += (len); \
580 if (++uio.uio_iovcnt >= NIOV) { \
581 if (BSD__sprint(fp, &uio)) \
586 #define PAD(howmany, with) { \
587 if ((n = (howmany)) > 0) { \
588 while (n > PADSIZE) { \
589 PRINT(with, PADSIZE); \
596 if (uio.uio_resid && BSD__sprint(fp, &uio)) \
598 uio.uio_iovcnt = 0; \
603 * To extend shorts properly, we need both signed and unsigned
604 * argument extraction methods.
607 (flags&LONGINT ? va_arg(ap, long) : \
608 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
609 (long)va_arg(ap, int))
611 (flags&LONGINT ? va_arg(ap, u_long) : \
612 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
613 (u_long)va_arg(ap, u_int))
615 /* optimise fprintf(stderr) (and other unbuffered Unix files) */
616 if ((fp
->_flags
& (__SNBF
|__SWR
|__SRW
)) == (__SNBF
|__SWR
) &&
618 return (BSD__sbprintf(fp
, fmt0
, ap
));
621 uio
.uio_iov
= iovp
= iov
;
628 * Scan the format for conversions (`%' character).
631 for (cp
= fmt
; (ch
= *fmt
) != '\0' && ch
!= '%'; fmt
++)
633 if ((n
= fmt
- cp
) != 0) {
639 fmt
++; /* skip over '%' */
648 reswitch
: switch (ch
) {
651 * ``If the space and + flags both appear, the space
652 * flag will be ignored.''
663 * ``A negative field width argument is taken as a
664 * - flag followed by a positive field width.''
666 * They don't exclude field widths read from args.
668 if ((width
= va_arg(ap
, int)) >= 0)
679 if ((ch
= *fmt
++) == '*') {
681 prec
= n
< 0 ? -1 : n
;
685 while (is_digit(ch
)) {
686 n
= 10 * n
+ to_digit(ch
);
689 prec
= n
< 0 ? -1 : n
;
693 * ``Note that 0 is taken as a flag, not as the
694 * beginning of a field width.''
699 case '1': case '2': case '3': case '4':
700 case '5': case '6': case '7': case '8': case '9':
703 n
= 10 * n
+ to_digit(ch
);
705 } while (is_digit(ch
));
708 #ifdef FLOATING_POINT
719 #ifdef _HAVE_SANE_QUAD_
723 #endif /* _HAVE_SANE_QUAD_ */
726 *buf
= (char)va_arg(ap
, int);
735 #ifdef _HAVE_SANE_QUAD_
736 if (flags
& QUADINT
) {
737 uqval
= va_arg(ap
, quad_t
);
738 if ((quad_t
)uqval
< 0) {
743 #endif /* _HAVE_SANE_QUAD_ */
746 if ((long)ulval
< 0) {
753 #ifdef FLOATING_POINT
754 case 'e': /* anomalous precision */
756 prec
= (prec
== -1) ?
757 DEFPREC
+ 1 : prec
+ 1;
760 case 'f': /* always print trailing zeroes */
767 fp_begin
: _double
= va_arg(ap
, double);
768 /* do this before tricky precision changes */
769 if (isinf(_double
)) {
776 if (isnan(_double
)) {
782 cp
= cvt(_double
, prec
, flags
, &softsign
,
784 if (ch
== 'g' || ch
== 'G') {
785 if (expt
<= -4 || expt
> prec
)
786 ch
= (ch
== 'g') ? 'e' : 'E';
790 if (ch
<= 'e') { /* 'e' or 'E' fmt */
792 expsize
= exponent(expstr
, expt
, ch
);
793 size
= expsize
+ ndig
;
794 if (ndig
> 1 || flags
& ALT
)
796 } else if (ch
== 'f') { /* f fmt */
799 if (prec
|| flags
& ALT
)
803 } else if (expt
>= ndig
) { /* fixed g fmt */
808 size
= ndig
+ (expt
> 0 ?
814 #endif /* FLOATING_POINT */
816 #ifdef _HAVE_SANE_QUAD_
818 *va_arg(ap
, quad_t
*) = ret
;
819 else if (flags
& LONGINT
)
820 #else /* _HAVE_SANE_QUAD_ */
822 #endif /* _HAVE_SANE_QUAD_ */
823 *va_arg(ap
, long *) = ret
;
824 else if (flags
& SHORTINT
)
825 *va_arg(ap
, short *) = ret
;
827 *va_arg(ap
, int *) = ret
;
828 continue; /* no output */
833 #ifdef _HAVE_SANE_QUAD_
835 uqval
= va_arg(ap
, u_quad_t
);
837 #endif /* _HAVE_SANE_QUAD_ */
843 * ``The argument shall be a pointer to void. The
844 * value of the pointer is converted to a sequence
845 * of printable characters, in an implementation-
849 prec
= sizeof(void*)*CHAR_BIT
/4;
851 uqval
= (u_long
)va_arg(ap
, void *);
852 flags
= (flags
) | QUADINT
| HEXPREFIX
;
854 ulval
= (u_long
)va_arg(ap
, void *);
855 #ifdef _HAVE_SANE_QUAD_
856 flags
= (flags
& ~QUADINT
) | HEXPREFIX
;
857 #else /* _HAVE_SANE_QUAD_ */
858 flags
= (flags
) | HEXPREFIX
;
859 #endif /* _HAVE_SANE_QUAD_ */
862 xdigs
= "0123456789abcdef";
866 if ((cp
= va_arg(ap
, char *)) == NULL
)
870 * can't use strlen; can only look for the
871 * NUL in the first `prec' characters, and
872 * strlen() will go further.
874 const char *p
= (char *)memchr(cp
, 0, prec
);
890 #ifdef _HAVE_SANE_QUAD_
892 uqval
= va_arg(ap
, u_quad_t
);
894 #endif /* _HAVE_SANE_QUAD_ */
899 xdigs
= "0123456789ABCDEF";
902 xdigs
= "0123456789abcdef";
904 #ifdef _HAVE_SANE_QUAD_
906 uqval
= va_arg(ap
, u_quad_t
);
908 #endif /* _HAVE_SANE_QUAD_ */
911 /* leading 0x/X only if non-zero */
913 #ifdef _HAVE_SANE_QUAD_
914 (flags
& QUADINT
? uqval
!= 0 : ulval
!= 0)
915 #else /* _HAVE_SANE_QUAD_ */
917 #endif /* _HAVE_SANE_QUAD_ */
921 /* unsigned conversions */
924 * ``... diouXx conversions ... if a precision is
925 * specified, the 0 flag will be ignored.''
928 number
: if ((dprec
= prec
) >= 0)
932 * ``The result of converting a zero value with an
933 * explicit precision of zero is no characters.''
936 #ifdef _HAVE_SANE_QUAD_
937 if (flags
& QUADINT
) {
938 if (uqval
!= 0 || prec
!= 0)
939 cp
= BSD__uqtoa(uqval
, ebuf
, base
,
942 #else /* _HAVE_SANE_QUAD_ */
943 #endif /* _HAVE_SANE_QUAD_ */
945 if (ulval
!= 0 || prec
!= 0)
946 cp
= BSD__ultoa(ulval
, ebuf
, base
,
951 default: /* "%?" prints ?, unless ? is NUL */
954 /* pretend it was %c with argument ch */
963 * All reasonable formats wind up here. At this point, `cp'
964 * points to a string which (if not flags&LADJUST) should be
965 * padded out to `width' places. If flags&ZEROPAD, it should
966 * first be prefixed by any sign or other prefix; otherwise,
967 * it should be blank padded before the prefix is emitted.
968 * After any left-hand padding and prefixing, emit zeroes
969 * required by a decimal [diouxX] precision, then print the
970 * string proper, then emit zeroes required by any leftover
971 * floating precision; finally, if LADJUST, pad with blanks.
973 * Compute actual size, so we know how much to pad.
974 * fieldsz excludes decimal prec; realsz includes it.
979 else if (flags
& HEXPREFIX
)
981 realsz
= dprec
> fieldsz
? dprec
: fieldsz
;
983 /* right-adjusting blank padding */
984 if ((flags
& (LADJUST
|ZEROPAD
)) == 0)
985 PAD(width
- realsz
, blanks
);
990 } else if (flags
& HEXPREFIX
) {
996 /* right-adjusting zero padding */
997 if ((flags
& (LADJUST
|ZEROPAD
)) == ZEROPAD
)
998 PAD(width
- realsz
, zeroes
);
1000 /* leading zeroes from decimal precision */
1001 PAD(dprec
- fieldsz
, zeroes
);
1003 /* the string or number proper */
1004 #ifdef FLOATING_POINT
1005 if ((flags
& FPT
) == 0) {
1007 } else { /* glue together f_p fragments */
1008 if (ch
>= 'f') { /* 'f' or 'g' */
1010 /* kludge for __dtoa irregularity */
1012 (flags
& ALT
) == 0) {
1016 PAD(ndig
- 1, zeroes
);
1018 } else if (expt
<= 0) {
1022 } else if (expt
>= ndig
) {
1024 PAD(expt
- ndig
, zeroes
);
1031 PRINT(cp
, ndig
-expt
);
1033 } else { /* 'e' or 'E' */
1034 if (ndig
> 1 || flags
& ALT
) {
1038 if (_double
|| flags
& ALT
== 0) {
1040 } else /* 0.[0..] */
1041 /* __dtoa irregularity */
1042 PAD(ndig
- 1, zeroes
);
1045 PRINT(expstr
, expsize
);
1051 /* left-adjusting padding (always blank) */
1052 if (flags
& LADJUST
)
1053 PAD(width
- realsz
, blanks
);
1055 /* finally, adjust ret */
1056 ret
+= width
> realsz
? width
: realsz
;
1058 FLUSH(); /* copy out the I/O vectors */
1063 return (__sferror(fp
) ? EOF
: ret
);
1067 #ifdef FLOATING_POINT
1069 extern char *BSD__dtoa
__P((double, int, int, int *, int *, char **));
1072 cvt(value
, ndigits
, flags
, sign
, decpt
, ch
, length
)
1074 int ndigits
, flags
, *decpt
, ch
, *length
;
1078 char *digits
, *bp
, *rve
;
1088 } else if (value
== 0.0 && 1.0/value
< 0) {
1093 digits
= BSD__dtoa(value
, mode
, ndigits
, decpt
, &dsgn
, &rve
);
1094 if (flags
& ALT
) { /* Print trailing zeros */
1095 bp
= digits
+ ndigits
;
1097 if (*digits
== '0' && value
)
1098 *decpt
= -ndigits
+ 1;
1101 if (value
== 0) /* kludge for __dtoa irregularity */
1106 *length
= rve
- digits
;
1111 exponent(p0
, exp
, fmtch
)
1115 register char *p
, *t
;
1116 char expbuf
[MAXEXP
];
1126 t
= expbuf
+ MAXEXP
;
1129 *--t
= to_char(exp
% 10);
1130 } while ((exp
/= 10) > 9);
1131 *--t
= to_char(exp
);
1132 for (; t
< expbuf
+ MAXEXP
; *p
++ = *t
++);
1136 *p
++ = to_char(exp
);
1140 #endif /* FLOATING_POINT */
1142 #ifndef HAVE_VSNPRINTF
1144 vsnprintf(str
, n
, fmt
, ap
)
1155 f
._flags
= __SWR
| __SSTR
;
1156 f
._bf
._base
= f
._p
= (unsigned char *)str
;
1157 f
._bf
._size
= f
._w
= n
- 1;
1158 f
.vwrite
= BSD__sfvwrite
;
1159 ret
= BSD_vfprintf(&f
, fmt
, ap
);
1165 #if defined(LIBC_SCCS) && !defined(lint)
1166 static char sccsid
[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
1167 #endif /* LIBC_SCCS and not lint */
1169 #ifndef HAVE_SNPRINTF
1171 #if defined(HAVE_STDARG_PROTOTYPES)
1172 snprintf(char *str
, size_t n
, char const *fmt
, ...)
1174 snprintf(str
, n
, fmt
, va_alist
)
1187 #if defined(HAVE_STDARG_PROTOTYPES)
1192 f
._flags
= __SWR
| __SSTR
;
1193 f
._bf
._base
= f
._p
= (unsigned char *)str
;
1194 f
._bf
._size
= f
._w
= n
- 1;
1195 f
.vwrite
= BSD__sfvwrite
;
1196 ret
= BSD_vfprintf(&f
, fmt
, ap
);