read-tree: migrate to parse-options
[git/mingw.git] / compat / snprintf.c
blob6c0fb056a571b30627e404d7f164de31ed1a8699
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 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ < 4
10 #define SNPRINTF_SIZE_CORR 1
11 #else
12 #define SNPRINTF_SIZE_CORR 0
13 #endif
14 #endif
16 #undef vsnprintf
17 int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
19 char *s;
20 int ret = -1;
22 if (maxsize > 0) {
23 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
24 if (ret == maxsize-1)
25 ret = -1;
26 /* Windows does not NUL-terminate if result fills buffer */
27 str[maxsize-1] = 0;
29 if (ret != -1)
30 return ret;
32 s = NULL;
33 if (maxsize < 128)
34 maxsize = 128;
36 while (ret == -1) {
37 maxsize *= 4;
38 str = realloc(s, maxsize);
39 if (! str)
40 break;
41 s = str;
42 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
43 if (ret == maxsize-1)
44 ret = -1;
46 free(s);
47 return ret;
50 int git_snprintf(char *str, size_t maxsize, const char *format, ...)
52 va_list ap;
53 int ret;
55 va_start(ap, format);
56 ret = git_vsnprintf(str, maxsize, format, ap);
57 va_end(ap);
59 return ret;