compat / snprintf.con commit Merge commit 'b319ef7' into jc/maint-fix-test-perm (00d3278)
   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