Mercurial > code
annotate port/C/asprintf.c @ 614:687b42509012
Misc: remove strip, there is alternative in boost
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 21 Aug 2017 11:14:05 +0200 |
parents | f48bb09bccc7 |
children | 266f32919d0a |
rev | line source |
---|---|
486 | 1 /* |
2 * asprintf.c -- basic port of asprintf / vsprintf functions | |
3 * | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
4 * Copyright (c) 2011-2016 David Demelier <markand@malikania.fr> |
486 | 5 * |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 #include <stdarg.h> | |
23 | |
24 /* | |
25 * The Microsoft implementation relies on the Win32 API function | |
26 * _vscprintf which count the number of characters needed. Otherwise the C99 | |
27 * function vsnprintf returns the number of character that would be printed. | |
28 * | |
29 * Finally, if we don't have C99, we use an optimistic function. | |
30 * | |
31 * The asprintf function is common to every implementations. | |
32 */ | |
33 | |
34 #if defined(_MSC_VER) | |
35 | |
36 /* | |
37 * Windows implementation. | |
38 */ | |
39 int | |
40 vasprintf(char **res, const char *fmt, va_list ap) | |
41 { | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
42 int total = _vscprintf(fmt, ap); |
486 | 43 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
44 if (total < 0) { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
45 *res = NULL; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
46 return -1; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
47 } |
486 | 48 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
49 if ((*res = (char *)malloc(sizeof (total) + 1)) == NULL) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
50 return -1; |
486 | 51 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
52 return vsprintf_s(*res, total + 1, fmt, ap); |
486 | 53 } |
54 | |
55 #elif __STDC_VERSION__ >= 199901L | |
56 | |
57 /* | |
58 * C99 implementation using vsnprintf's return value. | |
59 */ | |
60 int | |
61 vasprintf(char **res, const char *fmt, va_list ap) | |
62 { | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
63 int total, nwritten; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
64 va_list copy; |
486 | 65 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
66 va_copy(copy, ap); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
67 total = vsnprintf(NULL, 0, fmt, copy); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
68 va_end(copy); |
486 | 69 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
70 if (total < 0) { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
71 *res = NULL; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
72 return total; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
73 } |
486 | 74 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
75 if ((*res = malloc(total + 1)) == NULL) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
76 return -1; |
486 | 77 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
78 if ((nwritten = vsnprintf(*res, total + 1, fmt, ap)) < 0) { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
79 free(*res); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
80 *res = NULL; |
486 | 81 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
82 return -1; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
83 } |
486 | 84 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
85 return nwritten; |
486 | 86 } |
87 | |
88 #else | |
89 | |
90 /* | |
91 * Optimistic function fallback. | |
92 */ | |
93 int | |
94 vasprintf(char **res, const char *format, va_list ap) | |
95 { | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
96 int rvalue, ok; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
97 size_t base = 80; |
486 | 98 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
99 if ((*res = malloc(base)) == NULL) |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
100 return -1; |
486 | 101 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
102 ok = 0; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
103 do { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
104 rvalue = vsnprintf(*res, base, format, ap); |
486 | 105 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
106 if ((signed int)base <= rvalue || rvalue < 0) { |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
107 *res = realloc(*res, base * 2); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
108 base *= 2; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
109 } else |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
110 ok = 1; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
111 } while (!ok && *res != NULL); |
486 | 112 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
113 return rvalue; |
486 | 114 } |
115 | |
116 #endif | |
117 | |
118 int | |
119 asprintf(char **res, const char *fmt, ...) | |
120 { | |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
121 va_list ap; |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
122 int rvalue; |
486 | 123 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
124 va_start(ap, fmt); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
125 rvalue = vasprintf(res, fmt, ap); |
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
126 va_end(ap); |
486 | 127 |
548
f48bb09bccc7
Misc: huge cleanup, switch to spaces
David Demelier <markand@malikania.fr>
parents:
543
diff
changeset
|
128 return rvalue; |
486 | 129 } |