| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | /* Copyright (C) 2004       Manuel Novoa III    <mjn3@codepoet.org> * * GNU Library General Public License (LGPL) version 2 or later. * * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details. */#include "_stdio.h"#include <stdarg.h>#include <bits/uClibc_va_copy.h>#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!#elseint 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
 |