Merge commit 'refs/top-bases/girocco' into girocco
[git/repo.git] / compat / snprintf.c
blob357e733074ea7c85f880fa577ad65dfb3787fec7
1 #include "../git-compat-util.h"
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
12 #undef vsnprintf
13 int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
15 char *s;
16 int ret = -1;
18 if (maxsize > 0) {
19 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
20 if (ret == maxsize-1)
21 ret = -1;
22 /* Windows does not NUL-terminate if result fills buffer */
23 str[maxsize-1] = 0;
25 if (ret != -1)
26 return ret;
28 s = NULL;
29 if (maxsize < 128)
30 maxsize = 128;
32 while (ret == -1) {
33 maxsize *= 4;
34 str = realloc(s, maxsize);
35 if (! str)
36 break;
37 s = str;
38 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
39 if (ret == maxsize-1)
40 ret = -1;
42 free(s);
43 return ret;
46 int git_snprintf(char *str, size_t maxsize, const char *format, ...)
48 va_list ap;
49 int ret;
51 va_start(ap, format);
52 ret = git_vsnprintf(str, maxsize, format, ap);
53 va_end(ap);
55 return ret;