Merge branch 'bw/log-all-ref-updates-doc'
[gitweb.git] / compat / snprintf.c
index 580966e56a3455b9970b7eef33143c1e9c57d41c..e1e0e7543d9414726122c121b7909bf73809a81a 100644 (file)
@@ -2,12 +2,19 @@
 
 /*
  * The size parameter specifies the available space, i.e. includes
- * the trailing NUL byte; but Windows's vsnprintf expects the
- * number of characters to write without the trailing NUL.
+ * 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)
@@ -17,6 +24,8 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
 
        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;
        }
@@ -34,6 +43,8 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
                        break;
                s = str;
                ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
+               if (ret == maxsize-1)
+                       ret = -1;
        }
        free(s);
        return ret;