From 33f3e9d2c0a9db8b6f48ec0f9d79bdc3d0cd0cb7 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 29 Aug 2004 19:13:35 +0000 Subject: [PATCH] Add snprintf(), vsnprintf(). --- src/lib/lib.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++---- src/lib/lib.h | 6 ++++-- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/lib/lib.c b/src/lib/lib.c index 32c44e2..79dff9a 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -114,13 +114,13 @@ strchr (const char *string, int c_) return NULL; else string++; } - + static void vprintf_core (const char *format, va_list args, void (*output) (char, void *), void *aux); static void -output_console (char ch, void *aux __attribute__ ((unused))) +vprintk_helper (char ch, void *aux __attribute__ ((unused))) { vga_putc (ch); serial_outb (ch); @@ -130,7 +130,7 @@ void vprintk (const char *format, va_list args) { enum if_level old_level = intr_disable (); - vprintf_core (format, args, output_console, NULL); + vprintf_core (format, args, vprintk_helper, NULL); intr_set_level (old_level); } @@ -144,6 +144,50 @@ printk (const char *format, ...) va_end (args); } +struct vsnprintf_aux + { + char *p; + int length; + int max_length; + }; + +static void +vsnprintf_helper (char ch, void *aux_) +{ + struct vsnprintf_aux *aux = aux_; + + if (aux->length++ < aux->max_length) + *aux->p++ = ch; +} + +int +vsnprintf (char *buffer, size_t buf_size, + const char *format, va_list args) +{ + struct vsnprintf_aux aux; + aux.p = buffer; + aux.length = 0; + aux.max_length = buf_size > 0 ? buf_size - 1 : 0; + + vprintf_core (format, args, vsnprintf_helper, &aux); + + if (buf_size > 0) + *aux.p = '\0'; + + return aux.length; +} + +int +snprintf (char *buffer, size_t buf_size, + const char *format, ...) +{ + va_list args; + + va_start (args, format); + vsnprintf (buffer, buf_size, format, args); + va_end (args); +} + /* printf() and friends internals. You do not need to understand this code. */ @@ -177,7 +221,8 @@ struct printf_conversion }; static const char * -parse_conversion (const char *format, struct printf_conversion *c, va_list *args) +parse_conversion (const char *format, struct printf_conversion *c, + va_list *args) { /* Parse flag characters. */ c->flags = 0; diff --git a/src/lib/lib.h b/src/lib/lib.h index 668f904..405b9f7 100644 --- a/src/lib/lib.h +++ b/src/lib/lib.h @@ -3,6 +3,7 @@ #include #include +#include "debug.h" #define ROUND_UP(X, STEP) (((X) + (STEP) - 1) / (STEP) * (STEP)) #define DIV_ROUND_UP(X, STEP) (((X) + (STEP) - 1) / (STEP)) @@ -19,8 +20,9 @@ size_t strlcpy (char *, const char *, size_t); size_t strlen (const char *); void vprintk (const char *, va_list); -void printk (const char *, ...) - __attribute__ ((format (printf, 1, 2))); +void printk (const char *, ...) PRINTF_FORMAT (1, 2); +int vsnprintf (char *, size_t, const char *, va_list); +int snprintf (char *, size_t, const char *, ...) PRINTF_FORMAT (3, 4); static inline int isdigit (int c) -- 2.30.2