Add support for snprintf() to libstand.
Reviewed by: brooks @ Sponsored by: DARPA, AFRL
This commit is contained in:
parent
c46713e636
commit
8278e27fd2
@ -56,8 +56,16 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
|
||||
|
||||
typedef void (kvprintf_fn_t)(int, void *);
|
||||
|
||||
static char *ksprintn (char *buf, uintmax_t num, int base, int *len, int upper);
|
||||
static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
|
||||
static int kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap);
|
||||
|
||||
static void
|
||||
putchar_wrapper(int cc, void *arg)
|
||||
{
|
||||
putchar(cc);
|
||||
}
|
||||
|
||||
int
|
||||
printf(const char *fmt, ...)
|
||||
@ -66,7 +74,7 @@ printf(const char *fmt, ...)
|
||||
int retval;
|
||||
|
||||
va_start(ap, fmt);
|
||||
retval = kvprintf(fmt, putchar, NULL, 10, ap);
|
||||
retval = kvprintf(fmt, putchar_wrapper, NULL, 10, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
@ -74,8 +82,7 @@ printf(const char *fmt, ...)
|
||||
void
|
||||
vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
|
||||
kvprintf(fmt, putchar, NULL, 10, ap);
|
||||
kvprintf(fmt, putchar_wrapper, NULL, 10, ap);
|
||||
}
|
||||
|
||||
int
|
||||
@ -91,6 +98,46 @@ sprintf(char *buf, const char *cfmt, ...)
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct print_buf {
|
||||
char *buf;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static void
|
||||
snprint_func(int ch, void *arg)
|
||||
{
|
||||
struct print_buf *pbuf = arg;
|
||||
|
||||
if (pbuf->size < 2) {
|
||||
/*
|
||||
* Reserve last buffer position for the terminating
|
||||
* character:
|
||||
*/
|
||||
return;
|
||||
}
|
||||
*(pbuf->buf)++ = ch;
|
||||
pbuf->size--;
|
||||
}
|
||||
|
||||
int
|
||||
snprintf(char *buf, size_t size, const char *cfmt, ...)
|
||||
{
|
||||
int retval;
|
||||
va_list ap;
|
||||
struct print_buf arg;
|
||||
|
||||
arg.buf = buf;
|
||||
arg.size = size;
|
||||
|
||||
va_start(ap, cfmt);
|
||||
retval = kvprintf(cfmt, &snprint_func, &arg, 10, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (arg.size >= 1)
|
||||
*(arg.buf)++ = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
vsprintf(char *buf, const char *cfmt, va_list ap)
|
||||
{
|
||||
@ -149,9 +196,9 @@ ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
||||
* ("%*D", len, ptr, " " -> XX XX XX XX ...
|
||||
*/
|
||||
static int
|
||||
kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
|
||||
kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap)
|
||||
{
|
||||
#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
|
||||
#define PCHAR(c) {int cc=(c); if (func) (*func)(cc, arg); else *d++ = cc; retval++; }
|
||||
char nbuf[MAXNBUF];
|
||||
char *d;
|
||||
const char *p, *percent, *q;
|
||||
|
@ -238,6 +238,7 @@ extern void mallocstats(void);
|
||||
extern int printf(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void vprintf(const char *fmt, __va_list);
|
||||
extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3);
|
||||
extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4);
|
||||
extern void vsprintf(char *buf, const char *cfmt, __va_list);
|
||||
|
||||
extern void twiddle(void);
|
||||
|
Loading…
Reference in New Issue
Block a user