From 3c723734a8375cf040bc4ddf113fba7cf262c65c Mon Sep 17 00:00:00 2001 From: John Zimmermann Date: Sat, 21 Oct 2023 20:47:01 +0200 Subject: [PATCH] Add obstack_vprint function closes #9 --- obstack.h | 2 ++ obstack_printf.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/obstack.h b/obstack.h index a9cbc39..b570314 100644 --- a/obstack.h +++ b/obstack.h @@ -110,6 +110,7 @@ #include /* For size_t and ptrdiff_t. */ #include /* For __GNU_LIBRARY__, and memcpy. */ +#include /* For va_list. */ #if _OBSTACK_INTERFACE_VERSION == 1 /* For binary compatibility with obstack version 1, which used "int" @@ -213,6 +214,7 @@ extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *) /* Declare obstack_printf; it's in obstack_printf.c. */ extern int obstack_printf(struct obstack *obstack, const char *__restrict fmt, ...); +extern int obstack_vprintf(struct obstack *obstack, const char *__restrict fmt, va_list args); /* Error handler called when 'obstack_chunk_alloc' failed to allocate diff --git a/obstack_printf.c b/obstack_printf.c index ac5a7a3..1cdb281 100644 --- a/obstack_printf.c +++ b/obstack_printf.c @@ -1,18 +1,41 @@ #include #include #include +#include #include "obstack.h" int obstack_printf(struct obstack *obstack, const char *__restrict fmt, ...) { - char buf[1024]; va_list ap; int len; va_start(ap, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, ap); - obstack_grow(obstack, buf, len); + len = obstack_vprintf(obstack, fmt, ap); va_end(ap); return len; } + + +int obstack_vprintf (struct obstack *obstack, const char *__restrict fmt, va_list args) +{ + char buf[1024]; + size_t len; + char * str = buf; + + len = vsnprintf (buf, sizeof(buf), fmt, args); + if (len >= sizeof(buf)) { + str = NULL; + len = vasprintf(&str, fmt, args); + if (len < 0) { + free(str); + return -1; + } + } + obstack_grow (obstack, str, len); + + if (str != buf) + free(str); + + return len; +}