]> Git Repo - uclibc-ng.git/blame - libc/stdio/vasprintf.c
make sure TARGET_ARCH is set ... thought i committed this already?
[uclibc-ng.git] / libc / stdio / vasprintf.c
CommitLineData
082e680b
MNI
1/* Copyright (C) 2004 Manuel Novoa III <[email protected]>
2 *
3 * GNU Library General Public License (LGPL) version 2 or later.
4 *
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
7
8#include "_stdio.h"
9#include <stdarg.h>
371ca787 10#include <bits/uClibc_va_copy.h>
082e680b
MNI
11
12#ifdef __UCLIBC_MJN3_ONLY__
13/* Do the memstream stuff inline to avoid fclose and the openlist? */
14#warning CONSIDER: avoid open_memstream call?
15#endif
16
17#ifndef __STDIO_HAS_VSNPRINTF
18#warning Skipping vasprintf since no vsnprintf!
19#else
20
21int vasprintf(char **__restrict buf, const char * __restrict format,
22 va_list arg)
23{
24#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
25
26 FILE *f;
27 size_t size;
28 int rv = -1;
29
30 *buf = NULL;
31
32 if ((f = open_memstream(buf, &size)) != NULL) {
33 rv = vfprintf(f, format, arg);
34 fclose(f);
35 if (rv < 0) {
36 free(*buf);
37 *buf = NULL;
38 }
39 }
40
41 assert(rv >= -1);
42
43 return rv;
44
45#else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
46
47 /* This implementation actually calls the printf machinery twice, but only
48 * only does one malloc. This can be a problem though when custom printf
49 * specs or the %m specifier are involved because the results of the
50 * second call might be different from the first. */
51 va_list arg2;
52 int rv;
53
54 va_copy(arg2, arg);
55 rv = vsnprintf(NULL, 0, format, arg2);
56 va_end(arg2);
57
58 *buf = NULL;
59
60 if (rv >= 0) {
61 if ((*buf = malloc(++rv)) != NULL) {
62 if ((rv = vsnprintf(*buf, rv, format, arg)) < 0) {
63 free(*buf);
64 *buf = NULL;
65 }
66 }
67 }
68
69 assert(rv >= -1);
70
71 return rv;
72
73#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
74}
75
76#endif
This page took 0.074068 seconds and 4 git commands to generate.