71064e3f86
The code which is conditional on MinGW32 is actually conditional on Windows. Use the WIN32 symbol, which is defined by the MINGW32 and MSVC environments, but not by Cygwin. Define SNPRINTF_SIZE_CORR=1 for MSVC too, as its vsnprintf function does not add NUL at the end of the buffer if the result fits the buffer size exactly. Signed-off-by: Frank Li <lznuaa@gmail.com> Signed-off-by: Marius Storm-Olsen <mstormo@gmail.com> Acked-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
65 lines
1.4 KiB
C
65 lines
1.4 KiB
C
#include "../git-compat-util.h"
|
|
|
|
/*
|
|
* The size parameter specifies the available space, i.e. includes
|
|
* the trailing NUL byte; but Windows's vsnprintf uses the entire
|
|
* buffer and avoids the trailing NUL, should the buffer be exactly
|
|
* big enough for the result. Defining SNPRINTF_SIZE_CORR to 1 will
|
|
* therefore remove 1 byte from the reported buffer size, so we
|
|
* always have room for a trailing NUL byte.
|
|
*/
|
|
#ifndef SNPRINTF_SIZE_CORR
|
|
#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4)
|
|
#define SNPRINTF_SIZE_CORR 1
|
|
#else
|
|
#define SNPRINTF_SIZE_CORR 0
|
|
#endif
|
|
#endif
|
|
|
|
#undef vsnprintf
|
|
int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
|
|
{
|
|
char *s;
|
|
int ret = -1;
|
|
|
|
if (maxsize > 0) {
|
|
ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
|
|
if (ret == maxsize-1)
|
|
ret = -1;
|
|
/* Windows does not NUL-terminate if result fills buffer */
|
|
str[maxsize-1] = 0;
|
|
}
|
|
if (ret != -1)
|
|
return ret;
|
|
|
|
s = NULL;
|
|
if (maxsize < 128)
|
|
maxsize = 128;
|
|
|
|
while (ret == -1) {
|
|
maxsize *= 4;
|
|
str = realloc(s, maxsize);
|
|
if (! str)
|
|
break;
|
|
s = str;
|
|
ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
|
|
if (ret == maxsize-1)
|
|
ret = -1;
|
|
}
|
|
free(s);
|
|
return ret;
|
|
}
|
|
|
|
int git_snprintf(char *str, size_t maxsize, const char *format, ...)
|
|
{
|
|
va_list ap;
|
|
int ret;
|
|
|
|
va_start(ap, format);
|
|
ret = git_vsnprintf(str, maxsize, format, ap);
|
|
va_end(ap);
|
|
|
|
return ret;
|
|
}
|
|
|