compat / snprintf.con commit Merge branch 'db/vcs-helper' (cd03eeb)
   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