git
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 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.
10*/
11#ifndef SNPRINTF_SIZE_CORR12#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4) && (!defined(_MSC_VER) || _MSC_VER < 1900)13#define SNPRINTF_SIZE_CORR 114#else15#define SNPRINTF_SIZE_CORR 016#endif17#endif18
19#undef vsnprintf20int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)21{
22va_list cp;23char *s;24int ret = -1;25
26if (maxsize > 0) {27va_copy(cp, ap);28ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);29va_end(cp);30if (ret == maxsize-1)31ret = -1;32/* Windows does not NUL-terminate if result fills buffer */33str[maxsize-1] = 0;34}35if (ret != -1)36return ret;37
38s = NULL;39if (maxsize < 128)40maxsize = 128;41
42while (ret == -1) {43maxsize *= 4;44str = realloc(s, maxsize);45if (! str)46break;47s = str;48va_copy(cp, ap);49ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);50va_end(cp);51if (ret == maxsize-1)52ret = -1;53}54free(s);55return ret;56}
57
58int git_snprintf(char *str, size_t maxsize, const char *format, ...)59{
60va_list ap;61int ret;62
63va_start(ap, format);64ret = git_vsnprintf(str, maxsize, format, ap);65va_end(ap);66
67return ret;68}
69
70