From 082e680bd54e999f2bb4eb77141958938b1e9ee9 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Wed, 11 Feb 2004 23:48:50 +0000 Subject: New stdio core. Should be more maintainable. Fixes a couple of bugs. Codepaths streamlined. Improved performance for nonthreaded apps when linked with a thread-enabled libc. Minor iconv bug and some locale/thread related startup issues fixed. These showed up in getting a gcj-compiled java helloworld app running. Removed some old extension functions... _stdio_fdout and _stdio_fsfopen. --- libc/stdio/vasprintf.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 libc/stdio/vasprintf.c (limited to 'libc/stdio/vasprintf.c') diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c new file mode 100644 index 000000000..21ef8e145 --- /dev/null +++ b/libc/stdio/vasprintf.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2004 Manuel Novoa III + * + * GNU Library General Public License (LGPL) version 2 or later. + * + * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. + */ + +#include "_stdio.h" +#include + +#ifdef __UCLIBC_MJN3_ONLY__ +/* Do the memstream stuff inline to avoid fclose and the openlist? */ +#warning CONSIDER: avoid open_memstream call? +#endif + +#ifndef __STDIO_HAS_VSNPRINTF +#warning Skipping vasprintf since no vsnprintf! +#else + +int vasprintf(char **__restrict buf, const char * __restrict format, + va_list arg) +{ +#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ + + FILE *f; + size_t size; + int rv = -1; + + *buf = NULL; + + if ((f = open_memstream(buf, &size)) != NULL) { + rv = vfprintf(f, format, arg); + fclose(f); + if (rv < 0) { + free(*buf); + *buf = NULL; + } + } + + assert(rv >= -1); + + return rv; + +#else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ + + /* This implementation actually calls the printf machinery twice, but only + * only does one malloc. This can be a problem though when custom printf + * specs or the %m specifier are involved because the results of the + * second call might be different from the first. */ + va_list arg2; + int rv; + + va_copy(arg2, arg); + rv = vsnprintf(NULL, 0, format, arg2); + va_end(arg2); + + *buf = NULL; + + if (rv >= 0) { + if ((*buf = malloc(++rv)) != NULL) { + if ((rv = vsnprintf(*buf, rv, format, arg)) < 0) { + free(*buf); + *buf = NULL; + } + } + } + + assert(rv >= -1); + + return rv; + +#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ +} + +#endif -- cgit v1.2.3