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#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
15
16#undef vsnprintf
17int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
18{
19 char *s;
20 int ret = -1;
21
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;
28 }
29 if (ret != -1)
30 return ret;
31
32 s = NULL;
33 if (maxsize < 128)
34 maxsize = 128;
35
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;
45 }
46 free(s);
47 return ret;
48}
49
50int git_snprintf(char *str, size_t maxsize, const char *format, ...)
51{
52 va_list ap;
53 int ret;
54
55 va_start(ap, format);
56 ret = git_vsnprintf(str, maxsize, format, ap);
57 va_end(ap);
58
59 return ret;
60}
61