Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4aeceb4

Browse files
committed
Add asprintf.c
Forgotten in 5b6d08c
1 parent d3d3975 commit 4aeceb4

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

src/port/asprintf.c

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* src/port/asprintf.c */
2+
3+
/* $NetBSD: asprintf.c,v 1.3 2012/07/02 16:02:53 joerg Exp $ */
4+
5+
/*-
6+
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
7+
* All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions
11+
* are met:
12+
*
13+
* 1. Redistributions of source code must retain the above copyright
14+
* notice, this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright
16+
* notice, this list of conditions and the following disclaimer in
17+
* the documentation and/or other materials provided with the
18+
* distribution.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24+
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25+
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31+
* SUCH DAMAGE.
32+
*/
33+
34+
#include "c.h"
35+
36+
#define HAVE_VA_COPY 1
37+
38+
int
39+
asprintf(char **ret, const char *fmt, ...)
40+
{
41+
va_list ap;
42+
int retval;
43+
44+
va_start(ap, fmt);
45+
retval = vasprintf(ret, fmt, ap);
46+
va_end(ap);
47+
48+
return retval;
49+
}
50+
51+
int
52+
vasprintf(char **ret, const char *fmt, va_list ap)
53+
{
54+
char *buf, *new_buf;
55+
size_t len;
56+
int retval;
57+
va_list ap2;
58+
59+
len = 128;
60+
buf = malloc(len);
61+
if (buf == NULL) {
62+
*ret = NULL;
63+
return -1;
64+
}
65+
66+
#if defined(HAVE_VA_COPY)
67+
va_copy(ap2, ap);
68+
#define my_va_end(ap2) va_end(ap2)
69+
#elif defined(HAVE___BUILTIN_VA_COPY)
70+
__builtin_va_copy(ap2, ap);
71+
#define my_va_end(ap2) __builtin_va_end(ap2)
72+
#else
73+
ap2 = ap;
74+
#define my_va_end(ap2) do {} while (0)
75+
#endif
76+
retval = vsnprintf(buf, len, fmt, ap);
77+
if (retval < 0) {
78+
free(buf);
79+
*ret = NULL;
80+
va_end(ap2);
81+
return -1;
82+
}
83+
84+
if (retval < len) {
85+
new_buf = realloc(buf, retval + 1);
86+
if (new_buf == NULL)
87+
*ret = buf;
88+
else
89+
*ret = new_buf;
90+
my_va_end(ap2);
91+
return retval;
92+
}
93+
94+
len = (size_t)retval + 1;
95+
free(buf);
96+
buf = malloc(len);
97+
if (buf == NULL) {
98+
*ret = NULL;
99+
my_va_end(ap2);
100+
return -1;
101+
}
102+
retval = vsnprintf(buf, len, fmt, ap2);
103+
my_va_end(ap2);
104+
if (retval != len - 1) {
105+
free(buf);
106+
*ret = NULL;
107+
return -1;
108+
}
109+
*ret = buf;
110+
return retval;
111+
}

0 commit comments

Comments
 (0)