Add support for snprintf() to libstand.

Reviewed by:	brooks @
Sponsored by:	DARPA, AFRL
This commit is contained in:
Hans Petter Selasky 2014-05-30 09:43:32 +00:00
parent c46713e636
commit 8278e27fd2
2 changed files with 54 additions and 6 deletions

View File

@ -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;

View File

@ -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);