Code

Merge branch 'mr/compat-snprintf'
authorJunio C Hamano <gitster@pobox.com>
Sun, 9 Mar 2008 05:29:50 +0000 (21:29 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 9 Mar 2008 05:29:50 +0000 (21:29 -0800)
* mr/compat-snprintf:
  Add compat/snprintf.c for systems that return bogus

Makefile
compat/snprintf.c [new file with mode: 0644]
config.mak.in
configure.ac
git-compat-util.h

index 6e857e62c3d02fa2bfef7b9224e24d5b6a279c9c..7fbb81578264e47c83857e864e58b32c4f81a5fa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,10 @@ all::
 
 # Define V=1 to have a more verbose compile.
 #
+# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
+# or vsnprintf() return -1 instead of number of characters which would
+# have been written to the final string if enough space had been available.
+#
 # Define FREAD_READS_DIRECTORIES if your are on a system which succeeds
 # when attempting to read from an fopen'ed directory.
 #
@@ -630,6 +634,10 @@ endif
 ifdef NO_C99_FORMAT
        BASIC_CFLAGS += -DNO_C99_FORMAT
 endif
+ifdef SNPRINTF_RETURNS_BOGUS
+       COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
+       COMPAT_OBJS += compat/snprintf.o
+endif
 ifdef FREAD_READS_DIRECTORIES
        COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
        COMPAT_OBJS += compat/fopen.o
diff --git a/compat/snprintf.c b/compat/snprintf.c
new file mode 100644 (file)
index 0000000..dbfc2d6
--- /dev/null
@@ -0,0 +1,40 @@
+#include "../git-compat-util.h"
+
+#undef vsnprintf
+int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
+{
+       char *s;
+       int ret;
+
+       ret = vsnprintf(str, maxsize, format, ap);
+       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, format, ap);
+       }
+       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;
+}
+
index ee6c33df0385291623b900ac2b2cc088011b764d..8e1cd5f03de41ca929b6575ea8ed46e6bcfe2e7e 100644 (file)
@@ -46,3 +46,4 @@ NO_MKDTEMP=@NO_MKDTEMP@
 NO_ICONV=@NO_ICONV@
 OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
+SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@
index 85d7ef570d390d56d3ec3ba8af406eee30d700ea..287149d304b8a631d879bd3be7b059c6f074e5fe 100644 (file)
@@ -326,6 +326,40 @@ else
        NO_C99_FORMAT=
 fi
 AC_SUBST(NO_C99_FORMAT)
+#
+# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
+# or vsnprintf() return -1 instead of number of characters which would
+# have been written to the final string if enough space had been available.
+AC_CACHE_CHECK([whether snprintf() and/or vsnprintf() return bogus value],
+ [ac_cv_snprintf_returns_bogus],
+[
+AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
+               #include "stdarg.h"
+
+               int test_vsnprintf(char *str, size_t maxsize, const char *format, ...)
+               {
+                 int ret;
+                 va_list ap;
+                 va_start(ap, format);
+                 ret = vsnprintf(str, maxsize, format, ap);
+                 va_end(ap);
+                 return ret;
+               }],
+               [[char buf[6];
+                 if (test_vsnprintf(buf, 3, "%s", "12345") != 5
+                     || strcmp(buf, "12")) return 1;
+                 if (snprintf(buf, 3, "%s", "12345") != 5
+                     || strcmp(buf, "12")) return 1]])],
+       [ac_cv_snprintf_returns_bogus=no],
+       [ac_cv_snprintf_returns_bogus=yes])
+])
+if test $ac_cv_snprintf_returns_bogus = yes; then
+       SNPRINTF_RETURNS_BOGUS=UnfortunatelyYes
+else
+       SNPRINTF_RETURNS_BOGUS=
+fi
+AC_SUBST(SNPRINTF_RETURNS_BOGUS)
 
 
 ## Checks for library functions.
index 591244351ec4e410ea3b7f891d0de2f33a5aff7a..73968e02b024f22068eb5500033f7a2f41d31e8f 100644 (file)
@@ -209,6 +209,15 @@ void *gitmemmem(const void *haystack, size_t haystacklen,
 extern FILE *git_fopen(const char*, const char*);
 #endif
 
+#ifdef SNPRINTF_RETURNS_BOGUS
+#define snprintf git_snprintf
+extern int git_snprintf(char *str, size_t maxsize,
+                       const char *format, ...);
+#define vsnprintf git_vsnprintf
+extern int git_vsnprintf(char *str, size_t maxsize,
+                        const char *format, va_list ap);
+#endif
+
 #ifdef __GLIBC_PREREQ
 #if __GLIBC_PREREQ(2, 1)
 #define HAVE_STRCHRNUL