#include <sys/types.h>
#define u_long unsigned long
#define u_short unsigned short
#define u_int unsigned int
#undef __P
#if defined(__STDC__)
# include <stdarg.h>
# if !defined(__P)
# define __P(x) x
# endif
#else
# define __P(x) ()
# if !defined(const)
# define const
# endif
# include <varargs.h>
#endif
#ifndef _BSD_VA_LIST_
#define _BSD_VA_LIST_ va_list
#endif
#ifdef __STDC__
# include <limits.h>
#else
# ifndef LONG_MAX
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define LONG_MAX 2147483647
# endif
# endif
#endif
#if defined(__hpux) && !defined(__GNUC__)
#define const
#endif
#if defined(sgi)
#undef __const
#define __const
#endif
#include <stddef.h>
#ifndef NULL
#define NULL 0
#endif
struct __sbuf {
unsigned char *_base;
int _size;
};
typedef struct __sFILE {
unsigned char *_p;
int _r;
int _w;
short _flags;
short _file;
struct __sbuf _bf;
int _lbfsize;
} FILE;
#define __SLBF 0x0001
#define __SNBF 0x0002
#define __SRD 0x0004
#define __SWR 0x0008
#define __SRW 0x0010
#define __SEOF 0x0020
#define __SERR 0x0040
#define __SMBF 0x0080
#define __SAPP 0x0100
#define __SSTR 0x0200
#define __SOPT 0x0400
#define __SNPT 0x0800
#define __SOFF 0x1000
#define __SMOD 0x2000
#define EOF (-1)
#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
#define __sferror(p) (((p)->_flags & __SERR) != 0)
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
#define feof(p) __sfeof(p)
#define ferror(p) __sferror(p)
#define clearerr(p) __sclearerr(p)
#ifndef _ANSI_SOURCE
#define fileno(p) __sfileno(p)
#endif
#if defined(__hpux) && !defined(__GNUC__)
#include <string.h>
#endif
struct __siov {
void *iov_base;
size_t iov_len;
};
struct __suio {
struct __siov *uio_iov;
int uio_iovcnt;
int uio_resid;
};
static BSD__sfvwrite(fp, uio)
register FILE *fp;
register struct __suio *uio;
{
register size_t len;
register char *p;
register struct __siov *iov;
register int w;
if ((len = uio->uio_resid) == 0)
return (0);
#ifndef __hpux
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
iov = uio->uio_iov;
p = iov->iov_base;
len = iov->iov_len;
iov++;
#define GETIOV(extra_work) \
while (len == 0) { \
extra_work; \
p = iov->iov_base; \
len = iov->iov_len; \
iov++; \
}
if (fp->_flags & __SNBF) {
} else if ((fp->_flags & __SLBF) == 0) {
do {
GETIOV(;);
w = fp->_w;
if (fp->_flags & __SSTR) {
if (len < w)
w = len;
COPY(w);
fp->_w -= w;
fp->_p += w;
w = len;
} else {
}
p += w;
len -= w;
} while ((uio->uio_resid -= w) != 0);
} else {
}
return (0);
err:
fp->_flags |= __SERR;
return (EOF);
}
#if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__)
#include <stdlib.h>
#endif
static int
BSD__sprint(fp, uio)
FILE *fp;
register struct __suio *uio;
{
register int err;
if (uio->uio_resid == 0) {
uio->uio_iovcnt = 0;
return (0);
}
err = BSD__sfvwrite(fp, uio);
uio->uio_resid = 0;
uio->uio_iovcnt = 0;
return (err);
}
static int
BSD__sbprintf(fp, fmt, ap)
register FILE *fp;
const char *fmt;
va_list ap;
{
return 0;
}
#define to_digit(c) ((c) - '0')
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
#define to_char(n) ((n) + '0')
static char *
BSD__ultoa(val, endp, base, octzero, xdigs)
register u_long val;
char *endp;
int base, octzero;
char *xdigs;
{
register char *cp = endp;
register long sval;
switch (base) {
case 10:
if (val < 10) {
*--cp = to_char(val);
return (cp);
}
if (val > LONG_MAX) {
*--cp = to_char(val % 10);
sval = val / 10;
} else
sval = val;
do {
*--cp = to_char(sval % 10);
sval /= 10;
} while (sval != 0);
break;
case 8:
do {
*--cp = to_char(val & 7);
val >>= 3;
} while (val);
if (octzero && *cp != '0')
*--cp = '0';
break;
case 16:
do {
*--cp = xdigs[val & 15];
val >>= 4;
} while (val);
break;
default:
break;
}
return (cp);
}
#ifdef FLOATING_POINT
#include <math.h>
#ifndef MAXEXP
# define MAXEXP 1024
#endif
#ifndef MAXFRACT
# define MAXFRACT 64
#endif
#define BUF (MAXEXP+MAXFRACT+1)
#define DEFPREC 6
static char *cvt __P((double, int, int, char *, int *, int, int *));
static int exponent __P((char *, int, int));
#else
#define BUF 68
#endif
#define ALT 0x001
#define HEXPREFIX 0x002
#define LADJUST 0x004
#define LONGDBL 0x008
#define LONGINT 0x010
#ifdef _HAVE_SANE_QUAD_
#define QUADINT 0x020
#endif
#define SHORTINT 0x040
#define ZEROPAD 0x080
#define FPT 0x100
static int
BSD_vfprintf(fp, fmt0, ap)
FILE *fp;
const char *fmt0;
va_list ap;
{
register char *fmt;
register int ch;
register int n;
register char *cp;
register struct __siov *iovp;
register int flags;
int ret;
int width;
int prec;
char sign;
#ifdef FLOATING_POINT
char softsign;
double _double;
int expt;
int expsize;
int ndig;
char expstr[7];
#endif
u_long ulval;
#ifdef _HAVE_SANE_QUAD_
u_quad_t uqval;
#endif
int base;
int dprec;
int fieldsz;
int realsz;
int size;
char *xdigs;
#define NIOV 8
struct __suio uio;
struct __siov iov[NIOV];
char buf[BUF];
char ox[2];
#define PADSIZE 16
static char blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
#define PRINT(ptr, len) { \
iovp->iov_base = (ptr); \
iovp->iov_len = (len); \
uio.uio_resid += (len); \
iovp++; \
if (++uio.uio_iovcnt >= NIOV) { \
if (BSD__sprint(fp, &uio)) \
goto error; \
iovp = iov; \
} \
}
#define PAD(howmany, with) { \
if ((n = (howmany)) > 0) { \
while (n > PADSIZE) { \
PRINT(with, PADSIZE); \
n -= PADSIZE; \
} \
PRINT(with, n); \
} \
}
#define FLUSH() { \
if (uio.uio_resid && BSD__sprint(fp, &uio)) \
goto error; \
uio.uio_iovcnt = 0; \
iovp = iov; \
}
#define SARG() \
(flags&LONGINT ? va_arg(ap, long) : \
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
(long)va_arg(ap, int))
#define UARG() \
(flags&LONGINT ? va_arg(ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
(u_long)va_arg(ap, u_int))
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
return (BSD__sbprintf(fp, fmt0, ap));
fmt = (char *)fmt0;
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
ret = 0;
for (;;) {
for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
;
if ((n = fmt - cp) != 0) {
PRINT(cp, n);
ret += n;
}
if (ch == '\0')
goto done;
fmt++;
flags = 0;
dprec = 0;
width = 0;
prec = -1;
sign = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
case ' ':
if (!sign)
sign = ' ';
goto rflag;
case '#':
flags |= ALT;
goto rflag;
case '*':
if ((width = va_arg(ap, int)) >= 0)
goto rflag;
width = -width;
case '-':
flags |= LADJUST;
goto rflag;
case '+':
sign = '+';
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
n = va_arg(ap, int);
prec = n < 0 ? -1 : n;
goto rflag;
}
n = 0;
while (is_digit(ch)) {
n = 10 * n + to_digit(ch);
ch = *fmt++;
}
prec = n < 0 ? -1 : n;
goto reswitch;
case '0':
flags |= ZEROPAD;
goto rflag;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = 0;
do {
n = 10 * n + to_digit(ch);
ch = *fmt++;
} while (is_digit(ch));
width = n;
goto reswitch;
#ifdef FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
#endif
case 'h':
flags |= SHORTINT;
goto rflag;
case 'l':
flags |= LONGINT;
goto rflag;
#ifdef _HAVE_SANE_QUAD_
case 'q':
flags |= QUADINT;
goto rflag;
#endif
case 'c':
*(cp = buf) = va_arg(ap, int);
size = 1;
sign = '\0';
break;
case 'D':
flags |= LONGINT;
case 'd':
case 'i':
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT) {
uqval = va_arg(ap, quad_t);
if ((quad_t)uqval < 0) {
uqval = -uqval;
sign = '-';
}
} else {
#else
{
#endif
ulval = SARG();
if ((long)ulval < 0) {
ulval = -ulval;
sign = '-';
}
}
base = 10;
goto number;
#ifdef FLOATING_POINT
case 'e':
case 'E':
prec = (prec == -1) ?
DEFPREC + 1 : prec + 1;
goto fp_begin;
case 'f':
if (prec != 0)
flags |= ALT;
case 'g':
case 'G':
if (prec == -1)
prec = DEFPREC;
fp_begin: _double = va_arg(ap, double);
if (isinf(_double)) {
if (_double < 0)
sign = '-';
cp = "Inf";
size = 3;
break;
}
if (isnan(_double)) {
cp = "NaN";
size = 3;
break;
}
flags |= FPT;
cp = cvt(_double, prec, flags, &softsign,
&expt, ch, &ndig);
if (ch == 'g' || ch == 'G') {
if (expt <= -4 || expt > prec)
ch = (ch == 'g') ? 'e' : 'E';
else
ch = 'g';
}
if (ch <= 'e') {
--expt;
expsize = exponent(expstr, expt, ch);
size = expsize + ndig;
if (ndig > 1 || flags & ALT)
++size;
} else if (ch == 'f') {
if (expt > 0) {
size = expt;
if (prec || flags & ALT)
size += prec + 1;
} else
size = prec + 2;
} else if (expt >= ndig) {
size = expt;
if (flags & ALT)
++size;
} else
size = ndig + (expt > 0 ?
1 : 2 - expt);
if (softsign)
sign = '-';
break;
#endif
case 'n':
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT)
*va_arg(ap, quad_t *) = ret;
else if (flags & LONGINT)
#else
if (flags & LONGINT)
#endif
*va_arg(ap, long *) = ret;
else if (flags & SHORTINT)
*va_arg(ap, short *) = ret;
else
*va_arg(ap, int *) = ret;
continue;
case 'O':
flags |= LONGINT;
case 'o':
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT)
uqval = va_arg(ap, u_quad_t);
else
#endif
ulval = UARG();
base = 8;
goto nosign;
case 'p':
ulval = (u_long)va_arg(ap, void *);
base = 16;
xdigs = "0123456789abcdef";
#ifdef _HAVE_SANE_QUAD_
flags = (flags & ~QUADINT) | HEXPREFIX;
#else
flags = (flags) | HEXPREFIX;
#endif
ch = 'x';
goto nosign;
case 's':
if ((cp = va_arg(ap, char *)) == NULL)
cp = "(null)";
if (prec >= 0) {
char *p = (char *)memchr(cp, 0, prec);
if (p != NULL) {
size = p - cp;
if (size > prec)
size = prec;
} else
size = prec;
} else
size = strlen(cp);
sign = '\0';
break;
case 'U':
flags |= LONGINT;
case 'u':
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT)
uqval = va_arg(ap, u_quad_t);
else
#endif
ulval = UARG();
base = 10;
goto nosign;
case 'X':
xdigs = "0123456789ABCDEF";
goto hex;
case 'x':
xdigs = "0123456789abcdef";
hex:
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT)
uqval = va_arg(ap, u_quad_t);
else
#endif
ulval = UARG();
base = 16;
if (flags & ALT &&
#ifdef _HAVE_SANE_QUAD_
(flags & QUADINT ? uqval != 0 : ulval != 0))
#else
ulval != 0)
#endif
flags |= HEXPREFIX;
nosign: sign = '\0';
number: if ((dprec = prec) >= 0)
flags &= ~ZEROPAD;
cp = buf + BUF;
#ifdef _HAVE_SANE_QUAD_
if (flags & QUADINT) {
if (uqval != 0 || prec != 0)
cp = __uqtoa(uqval, cp, base,
flags & ALT, xdigs);
} else {
#else
{
#endif
if (ulval != 0 || prec != 0)
cp = BSD__ultoa(ulval, cp, base,
flags & ALT, xdigs);
}
size = buf + BUF - cp;
break;
default:
if (ch == '\0')
goto done;
cp = buf;
*cp = ch;
size = 1;
sign = '\0';
break;
}
fieldsz = size;
if (sign)
fieldsz++;
else if (flags & HEXPREFIX)
fieldsz += 2;
realsz = dprec > fieldsz ? dprec : fieldsz;
if ((flags & (LADJUST|ZEROPAD)) == 0)
PAD(width - realsz, blanks);
if (sign) {
PRINT(&sign, 1);
} else if (flags & HEXPREFIX) {
ox[0] = '0';
ox[1] = ch;
PRINT(ox, 2);
}
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD(width - realsz, zeroes);
PAD(dprec - fieldsz, zeroes);
#ifdef FLOATING_POINT
if ((flags & FPT) == 0) {
PRINT(cp, size);
} else {
if (ch >= 'f') {
if (_double == 0) {
if (prec == 0 ||
(flags & ALT) == 0) {
PRINT("0", 1);
} else {
PRINT("0.", 2);
PAD(ndig - 1, zeroes);
}
} else if (expt <= 0) {
PRINT("0.", 2);
PAD(-expt, zeroes);
PRINT(cp, ndig);
} else if (expt >= ndig) {
PRINT(cp, ndig);
PAD(expt - ndig, zeroes);
if (flags & ALT)
PRINT(".", 1);
} else {
PRINT(cp, expt);
cp += expt;
PRINT(".", 1);
PRINT(cp, ndig-expt);
}
} else {
if (ndig > 1 || flags & ALT) {
ox[0] = *cp++;
ox[1] = '.';
PRINT(ox, 2);
if (_double || flags & ALT == 0) {
PRINT(cp, ndig-1);
} else
PAD(ndig - 1, zeroes);
} else
PRINT(cp, 1);
PRINT(expstr, expsize);
}
}
#else
PRINT(cp, size);
#endif
if (flags & LADJUST)
PAD(width - realsz, blanks);
ret += width > realsz ? width : realsz;
FLUSH();
}
done:
FLUSH();
error:
return (__sferror(fp) ? EOF : ret);
}
#ifdef FLOATING_POINT
extern char *BSD__dtoa __P((double, int, int, int *, int *, char **));
static char *
cvt(value, ndigits, flags, sign, decpt, ch, length)
double value;
int ndigits, flags, *decpt, ch, *length;
char *sign;
{
int mode, dsgn;
char *digits, *bp, *rve;
if (ch == 'f')
mode = 3;
else {
mode = 2;
}
if (value < 0) {
value = -value;
*sign = '-';
} else
*sign = '\000';
digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
if (flags & ALT) {
bp = digits + ndigits;
if (ch == 'f') {
if (*digits == '0' && value)
*decpt = -ndigits + 1;
bp += *decpt;
}
if (value == 0)
rve = bp;
while (rve < bp)
*rve++ = '0';
}
*length = rve - digits;
return (digits);
}
static int
exponent(p0, exp, fmtch)
char *p0;
int exp, fmtch;
{
register char *p, *t;
char expbuf[MAXEXP];
p = p0;
*p++ = fmtch;
if (exp < 0) {
exp = -exp;
*p++ = '-';
}
else
*p++ = '+';
t = expbuf + MAXEXP;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAXEXP; *p++ = *t++);
}
else {
*p++ = '0';
*p++ = to_char(exp);
}
return (p - p0);
}
#endif
int
vsnprintf(str, n, fmt, ap)
char *str;
size_t n;
const char *fmt;
_BSD_VA_LIST_ ap;
{
int ret;
FILE f;
if ((int)n < 1)
return (EOF);
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n - 1;
ret = BSD_vfprintf(&f, fmt, ap);
*f._p = 0;
return (ret);
}
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
#endif
#if defined(__STDC__)
# include <stdarg.h>
#else
# include <varargs.h>
#endif
int
#if defined(__STDC__)
snprintf(char *str, size_t n, char const *fmt, ...)
#else
snprintf(str, n, fmt, va_alist)
char *str, *fmt;
size_t n;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
if ((int)n < 1)
return (EOF);
#if defined(__STDC__)
va_start(ap, fmt);
#else
va_start(ap);
#endif
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n - 1;
ret = BSD_vfprintf(&f, fmt, ap);
*f._p = 0;
va_end(ap);
return (ret);
}