Commit | Line | Data |
---|---|---|
0c1f3509 MG |
1 | #include <stdarg.h> |
2 | #include <stdio.h> | |
3 | #include <stdlib.h> | |
4 | ||
5 | #include "asprintf.h" | |
6 | ||
7 | /** | |
8 | * asprintf(ret, format, ...): | |
9 | * Do asprintf(3) like GNU and BSD do. | |
10 | */ | |
11 | int | |
12 | asprintf(char ** ret, const char * format, ...) | |
13 | { | |
14 | va_list ap; | |
15 | int len; | |
16 | size_t buflen; | |
17 | ||
18 | /* Figure out how long the string needs to be. */ | |
19 | va_start(ap, format); | |
20 | len = vsnprintf(NULL, 0, format, ap); | |
21 | va_end(ap); | |
22 | ||
23 | /* Did we fail? */ | |
24 | if (len < 0) | |
25 | goto err0; | |
26 | buflen = (size_t)(len) + 1; | |
27 | ||
28 | /* Allocate memory. */ | |
29 | if ((*ret = malloc(buflen)) == NULL) | |
30 | goto err0; | |
31 | ||
32 | /* Actually generate the string. */ | |
33 | va_start(ap, format); | |
34 | len = vsnprintf(*ret, buflen, format, ap); | |
35 | va_end(ap); | |
36 | ||
37 | /* Did we fail? */ | |
38 | if (len < 0) | |
39 | goto err1; | |
40 | ||
41 | /* Success! */ | |
42 | return (len); | |
43 | ||
44 | err1: | |
45 | free(*ret); | |
46 | err0: | |
47 | /* Failure! */ | |
48 | return (-1); | |
49 | } |