Merge commit 'v1.6.0' into jc/checkout-reflog-fix
[git] / compat / snprintf.c
1 #include "../git-compat-util.h"
2
3 /*
4  * The size parameter specifies the available space, i.e. includes
5  * the trailing NUL byte; but Windows's vsnprintf expects the
6  * number of characters to write without the trailing NUL.
7  */
8 #ifndef SNPRINTF_SIZE_CORR
9 #define SNPRINTF_SIZE_CORR 0
10 #endif
11
12 #undef vsnprintf
13 int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
14 {
15         char *s;
16         int ret = -1;
17
18         if (maxsize > 0) {
19                 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
20                 /* Windows does not NUL-terminate if result fills buffer */
21                 str[maxsize-1] = 0;
22         }
23         if (ret != -1)
24                 return ret;
25
26         s = NULL;
27         if (maxsize < 128)
28                 maxsize = 128;
29
30         while (ret == -1) {
31                 maxsize *= 4;
32                 str = realloc(s, maxsize);
33                 if (! str)
34                         break;
35                 s = str;
36                 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
37         }
38         free(s);
39         return ret;
40 }
41
42 int git_snprintf(char *str, size_t maxsize, const char *format, ...)
43 {
44         va_list ap;
45         int ret;
46
47         va_start(ap, format);
48         ret = git_vsnprintf(str, maxsize, format, ap);
49         va_end(ap);
50
51         return ret;
52 }
53