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, and does not necessarily write the
7 * trailing NUL.
8 */
9#ifndef SNPRINTF_SIZE_CORR
10#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ < 4
11#define SNPRINTF_SIZE_CORR 1
12#else
13#define SNPRINTF_SIZE_CORR 0
14#endif
15#endif
16
17#undef vsnprintf
18int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
19{
20 char *s;
21 int ret = -1;
22
23 if (maxsize > 0) {
24 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
25 if (ret == maxsize-1)
26 ret = -1;
27 /* Windows does not NUL-terminate if result fills buffer */
28 str[maxsize-1] = 0;
29 }
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;
43 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
44 if (ret == maxsize-1)
45 ret = -1;
46 }
47 free(s);
48 return ret;
49}
50
51int 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