From ad2fbd03f08e49f9da0ebe6133c33073244f01d2 Mon Sep 17 00:00:00 2001 From: nattthebear <goyuken@gmail.com> Date: Tue, 5 Apr 2016 21:19:23 -0400 Subject: [PATCH] Waterbox: a few small libc changes --- waterbox/libc/functions/stdio/vasprintf.c | 58 +++++++++++++++++++++++ waterbox/libc/includes/stdio.h | 3 ++ waterbox/libc/internals/_PDCLIB_config.h | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 waterbox/libc/functions/stdio/vasprintf.c diff --git a/waterbox/libc/functions/stdio/vasprintf.c b/waterbox/libc/functions/stdio/vasprintf.c new file mode 100644 index 0000000000..96bbe17f51 --- /dev/null +++ b/waterbox/libc/functions/stdio/vasprintf.c @@ -0,0 +1,58 @@ +#define _PDCLIB_EXTENSIONS +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +static size_t mcb(void *p, const char *buf, size_t size) +{ + *(size_t *)p += size; + return size; +} + +static size_t vprintflen(const char *restrict fmt, va_list arg) +{ + size_t ret = 0; + _vcbprintf(&ret, mcb, fmt, arg); + return ret + 1; +} + +int asprintf(char **strp, const char *restrict fmt, ...) +{ + va_list arg, arg2; + va_start(arg, fmt); + va_copy(arg2, arg); + + size_t sz = vprintflen(fmt, arg); + + *strp = malloc(sz); + if (!strp) + { + va_end(arg); + va_end(arg2); + return -1; + } + + int ret = vsnprintf(*strp, sz, fmt, arg2); + va_end(arg); + va_end(arg2); + return ret; +} + +int vasprintf(char **strp, const char *restrict fmt, va_list arg) +{ + va_list arg2; + va_copy(arg2, arg); + + size_t sz = vprintflen(fmt, arg); + + *strp = malloc(sz); + if (!strp) + { + va_end(arg2); + return -1; + } + + int ret = vsnprintf(*strp, sz, fmt, arg2); + va_end(arg2); + return ret; +} diff --git a/waterbox/libc/includes/stdio.h b/waterbox/libc/includes/stdio.h index 0d28ce7468..c70ad2f502 100644 --- a/waterbox/libc/includes/stdio.h +++ b/waterbox/libc/includes/stdio.h @@ -646,6 +646,9 @@ int vsprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _ */ int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; +int asprintf(char **strp, const char * _PDCLIB_restrict fmt, ...) _PDCLIB_nothrow; +int vasprintf(char **strp, const char * _PDCLIB_restrict fmt, _PDCLIB_va_list arg) _PDCLIB_nothrow; + /* Character input/output functions */ /* Retrieve the next character from given stream. diff --git a/waterbox/libc/internals/_PDCLIB_config.h b/waterbox/libc/internals/_PDCLIB_config.h index 3be7ca2aee..5aad2c6c07 100644 --- a/waterbox/libc/internals/_PDCLIB_config.h +++ b/waterbox/libc/internals/_PDCLIB_config.h @@ -278,7 +278,7 @@ struct _PDCLIB_imaxdiv_t typedef char * _PDCLIB_va_list; #define _PDCLIB_va_arg( ap, type ) ( (ap) += (_PDCLIB_va_round(type)), ( *(type*) ( (ap) - (_PDCLIB_va_round(type)) ) ) ) #define _PDCLIB_va_copy( dest, src ) ( (dest) = (src), (void)0 ) -#define _PDCLIB_va_end( ap ) ( (ap) = (void *)0, (void)0 ) +#define _PDCLIB_va_end( ap ) ( (ap) = (char *)0, (void)0 ) #define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 ) /* -------------------------------------------------------------------------- */