blob: 0b1168853778810d385c84625ad643587537913b [file] [log] [blame]
Michal Rokosc4582f92008-03-05 16:46:13 +01001#include "../git-compat-util.h"
2
Johannes Sixtf4626df2007-12-01 21:24:59 +01003/*
4 * The size parameter specifies the available space, i.e. includes
Frank Li71064e32009-09-16 10:20:22 +02005 * the trailing NUL byte; but Windows's vsnprintf uses the entire
6 * buffer and avoids the trailing NUL, should the buffer be exactly
7 * big enough for the result. Defining SNPRINTF_SIZE_CORR to 1 will
8 * therefore remove 1 byte from the reported buffer size, so we
9 * always have room for a trailing NUL byte.
Johannes Sixtf4626df2007-12-01 21:24:59 +010010 */
11#ifndef SNPRINTF_SIZE_CORR
Sven Strickrothdae26d32016-03-29 18:25:28 +020012#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4) && (!defined(_MSC_VER) || _MSC_VER < 1900)
Johannes Schindelinf90cf2b2009-05-31 18:15:15 +020013#define SNPRINTF_SIZE_CORR 1
14#else
Johannes Sixtf4626df2007-12-01 21:24:59 +010015#define SNPRINTF_SIZE_CORR 0
16#endif
Johannes Schindelinf90cf2b2009-05-31 18:15:15 +020017#endif
Johannes Sixtf4626df2007-12-01 21:24:59 +010018
Michal Rokosc4582f92008-03-05 16:46:13 +010019#undef vsnprintf
20int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
21{
Jeff Kinga9bfbc52011-12-12 09:25:51 -050022 va_list cp;
Michal Rokosc4582f92008-03-05 16:46:13 +010023 char *s;
Johannes Sixtf4626df2007-12-01 21:24:59 +010024 int ret = -1;
Michal Rokosc4582f92008-03-05 16:46:13 +010025
Johannes Sixtf4626df2007-12-01 21:24:59 +010026 if (maxsize > 0) {
Jeff Kinga9bfbc52011-12-12 09:25:51 -050027 va_copy(cp, ap);
28 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);
29 va_end(cp);
Brandon Caseya81892d2008-08-20 20:53:50 -050030 if (ret == maxsize-1)
31 ret = -1;
Johannes Sixtf4626df2007-12-01 21:24:59 +010032 /* Windows does not NUL-terminate if result fills buffer */
33 str[maxsize-1] = 0;
34 }
Michal Rokosc4582f92008-03-05 16:46:13 +010035 if (ret != -1)
36 return ret;
37
38 s = NULL;
39 if (maxsize < 128)
40 maxsize = 128;
41
42 while (ret == -1) {
43 maxsize *= 4;
44 str = realloc(s, maxsize);
45 if (! str)
46 break;
47 s = str;
Jeff Kinga9bfbc52011-12-12 09:25:51 -050048 va_copy(cp, ap);
49 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);
50 va_end(cp);
Brandon Caseya81892d2008-08-20 20:53:50 -050051 if (ret == maxsize-1)
52 ret = -1;
Michal Rokosc4582f92008-03-05 16:46:13 +010053 }
54 free(s);
55 return ret;
56}
57
58int git_snprintf(char *str, size_t maxsize, const char *format, ...)
59{
60 va_list ap;
61 int ret;
62
63 va_start(ap, format);
64 ret = git_vsnprintf(str, maxsize, format, ap);
65 va_end(ap);
66
67 return ret;
68}
69