Add snprintf and vsnprintf.
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 18 Apr 2005 07:55:09 +0000 (07:55 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Mon, 18 Apr 2005 07:55:09 +0000 (07:55 +0000)
lib/libstand/printf.c
lib/libstand/stand.h

index 469db8f..3cdbdc8 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)subr_prf.c  8.3 (Berkeley) 1/21/94
  * $FreeBSD: src/lib/libstand/printf.c,v 1.4 1999/12/27 08:45:14 peter Exp $
- * $DragonFly: src/lib/libstand/printf.c,v 1.4 2004/10/25 19:38:45 drhodus Exp $
+ * $DragonFly: src/lib/libstand/printf.c,v 1.5 2005/04/18 07:55:09 joerg Exp $
  */
 
 /*
  */
 #include <stdarg.h>
 
-static char    *ksprintn (u_long num, int base, int *len);
-static int     kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
+struct snprintf_arg {
+       char    *buf;
+       size_t  remain;
+};
+
+static char    *ksprintn(u_long, int, int *);
+static int     kvprintf(const char *, void (*)(int, void *), void *, int,
+                        va_list);
+static void    putchar_wrapper(int, void *);
+static void    snprintf_func(int, void *);
+
+static void
+putchar_wrapper(int ch, void *arg __unused)
+{
+       putchar(ch);
+}
 
 int
 printf(const char *fmt, ...)
@@ -64,7 +78,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;
 }
@@ -73,7 +87,7 @@ void
 vprintf(const char *fmt, va_list ap)
 {
 
-       kvprintf(fmt, putchar, NULL, 10, ap);
+       kvprintf(fmt, putchar_wrapper, NULL, 10, ap);
 }
 
 int
@@ -98,6 +112,43 @@ vsprintf(char *buf, const char *cfmt, va_list ap)
        buf[retval] = '\0';
 }
 
+int
+snprintf(char *buf, size_t size, const char *cfmt, ...)
+{
+       int retval;
+       va_list ap;
+
+       va_start(ap, cfmt);
+       retval = vsnprintf(buf, size, cfmt, ap);
+       __va_end(ap);
+       return(retval);
+}
+
+int
+vsnprintf(char *buf, size_t size, const char *cfmt, va_list ap)
+{
+       struct snprintf_arg info;
+       int retval;
+
+       info.buf = buf;
+       info.remain = size;
+       retval = kvprintf(cfmt, snprintf_func, &info, 10, ap);
+       if (info.remain >= 1)
+               *info.buf++ = '\0';
+       return(retval);
+}
+
+static void
+snprintf_func(int ch, void *arg)
+{
+       struct snprintf_arg * const info = arg;
+
+       if (info->remain >= 2) {
+               *info->buf++ = ch;
+               info->remain--;
+       }
+}
+
 /*
  * Put a number (base <= 16) in a buffer in reverse order; return an
  * optional length and a pointer to the NULL terminated (preceded?)
@@ -147,9 +198,10 @@ ksprintn(ul, base, lenp)
  *             ("%*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, void (*func)(int, void *), 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 *p, *q, *d;
        u_char *up;
        int ch, n;
index f890325..31860ad 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/lib/libstand/stand.h,v 1.18.2.8 2002/06/17 11:22:39 sobomax Exp $
- * $DragonFly: src/lib/libstand/stand.h,v 1.6 2005/03/13 15:10:03 swildner Exp $
+ * $DragonFly: src/lib/libstand/stand.h,v 1.7 2005/04/18 07:55:09 joerg Exp $
  * From        $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $      
  */
 
@@ -250,6 +250,8 @@ extern int  printf(const char *fmt, ...);
 extern void    vprintf(const char *fmt, __va_list va);
 extern int     sprintf(char *buf, const char *cfmt, ...);
 extern void    vsprintf(char *buf, const char *cfmt, __va_list va);
+int    snprintf(char *, size_t, const char *, ...);
+int    vsnprintf(char *, size_t, const char *, __va_list);
 
 extern void    twiddle(void);