]>
Commit | Line | Data |
---|---|---|
c4582f93 MR |
1 | #include "../git-compat-util.h" |
2 | ||
f4626df5 JS |
3 | /* |
4 | * The size parameter specifies the available space, i.e. includes | |
5 | * the trailing NUL byte; but Windows's vsnprintf expects the | |
d1094fdd JH |
6 | * number of characters to write, and does not necessarily write the |
7 | * trailing NUL. | |
f4626df5 JS |
8 | */ |
9 | #ifndef SNPRINTF_SIZE_CORR | |
f90cf2b9 JS |
10 | #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ < 4 |
11 | #define SNPRINTF_SIZE_CORR 1 | |
12 | #else | |
f4626df5 JS |
13 | #define SNPRINTF_SIZE_CORR 0 |
14 | #endif | |
f90cf2b9 | 15 | #endif |
f4626df5 | 16 | |
c4582f93 MR |
17 | #undef vsnprintf |
18 | int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) | |
19 | { | |
20 | char *s; | |
f4626df5 | 21 | int ret = -1; |
c4582f93 | 22 | |
f4626df5 JS |
23 | if (maxsize > 0) { |
24 | ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); | |
a81892dd BC |
25 | if (ret == maxsize-1) |
26 | ret = -1; | |
f4626df5 JS |
27 | /* Windows does not NUL-terminate if result fills buffer */ |
28 | str[maxsize-1] = 0; | |
29 | } | |
c4582f93 MR |
30 | if (ret != -1) |
31 | return ret; | |
32 | ||
33 | s = NULL; | |
34 | if (maxsize < 128) | |
35 | maxsize = 128; | |
36 | ||
37 | while (ret == -1) { | |
38 | maxsize *= 4; | |
39 | str = realloc(s, maxsize); | |
40 | if (! str) | |
41 | break; | |
42 | s = str; | |
f4626df5 | 43 | ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap); |
a81892dd BC |
44 | if (ret == maxsize-1) |
45 | ret = -1; | |
c4582f93 MR |
46 | } |
47 | free(s); | |
48 | return ret; | |
49 | } | |
50 | ||
51 | int git_snprintf(char *str, size_t maxsize, const char *format, ...) | |
52 | { | |
53 | va_list ap; | |
54 | int ret; | |
55 | ||
56 | va_start(ap, format); | |
57 | ret = git_vsnprintf(str, maxsize, format, ap); | |
58 | va_end(ap); | |
59 | ||
60 | return ret; | |
61 | } | |
62 |