Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix portability issue in vsnprintf

  • Loading branch information...
commit 6af8dd1015917d572b43a6f0ed2cf00ac69abe72 1 parent f23cacb
@tagoh authored
Showing with 94 additions and 13 deletions.
  1. +32 −1 configure.ac
  2. +62 −12 liblangtag/lt-utils.c
View
33 configure.ac
@@ -202,12 +202,43 @@ dnl functions testing
dnl ======================================================================
AX_CREATE_STDINT_H([liblangtag/lt-stdint.h])
AC_CHECK_HEADERS([dirent.h execinfo.h libgen.h sys/param.h])
-AC_CHECK_FUNCS([backtrace dlopen strndup])
+AC_CHECK_FUNCS([backtrace dlopen strndup vasprintf vsnprintf])
AC_CHECK_VA_COPY
if test "x$ac_cv_func_dlopen" != xyes; then
enable_modules=no
fi
+if test "x$ac_cv_func_vsnprintf" = xyes; then
+ AC_CACHE_CHECK([Whether vsnprintf is C99-compliant], [lt_cv_c99_vsnprintf],
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdarg.h>
+int
+foo(char *format, ...)
+{
+ va_list ap;
+ char c;
+ int retval = 0;
+
+ va_start(ap, format);
+ if (vsnprintf(&c, 1, format, ap) < 0) {
+ retval = -1;
+ }
+ va_end(ap);
+
+ return retval;
+}
+int
+main(void)
+{
+ char c;
+
+ return foo("foo: %s", "bar");
+}]])],
+ [lt_cv_c99_vsnprintf=yes],[lt_cv_c99_vsnprintf=no],[lt_cv_c99_vsnprintf=no])])
+ if test "x$lt_cv_c99_vsnprintf" = xyes; then
+ AC_DEFINE(LT_HAVE_C99_VSNPRINTF, 1, [Have C99-compliant vsnprintf])
+ fi
+fi
dnl ======================================================================
dnl gettext stuff
View
74 liblangtag/lt-utils.c
@@ -14,6 +14,10 @@
#include "config.h"
#endif
+#if HAVE_VASPRINTF
+#define _GNU_SOURCE
+#endif
+
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -126,22 +130,68 @@ char *
lt_strdup_vprintf(const char *format,
va_list args)
{
- char *retval, c;
- va_list ap;
- int size;
+ char *retval;
lt_return_val_if_fail (format != NULL, NULL);
- va_copy(ap, args);
-
- size = vsnprintf(&c, 1, format, ap) + 1;
-
- va_end(ap);
-
- retval = malloc(sizeof (char) * size);
- if (retval) {
- vsprintf(retval, format, args);
+#if HAVE_VASPRINTF
+ if (vasprintf(&retval, format, args) < 0) {
+ retval = NULL;
}
+#elif LT_HAVE_C99_VSNPRINTF
+ LT_STMT_START {
+ char c;
+ va_list ap;
+ int size;
+
+ va_copy(ap, args);
+
+ size = vsnprintf(&c, 1, format, ap) + 1;
+
+ va_end(ap);
+
+ retval = malloc(sizeof (char) * size);
+ if (retval) {
+ vsprintf(retval, format, args);
+ }
+ } LT_STMT_END;
+#elif HAVE_VSNPRINTF
+ LT_STMT_START {
+ va_list ap;
+ int size = 1024, n;
+ char *p;
+
+ retval = malloc(size);
+ if (!retval)
+ return NULL;
+
+ while (1) {
+ va_copy(ap, args);
+
+ n = vsnprintf(retval, size, format, ap);
+
+ va_end(ap);
+
+ if (n > -1 && n < size)
+ return retval;
+
+ if (n > -1)
+ size = n + 1;
+ else
+ size *= 2;
+
+ p = realloc(retval, size);
+ if (!p) {
+ free(retval);
+ retval = NULL;
+ break;
+ }
+ retval = p;
+ }
+ } LT_STMT_END;
+#else
+#error no vsnprintf function implemented.
+#endif
return retval;
}
Please sign in to comment.
Something went wrong with that request. Please try again.