summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure153
-rw-r--r--configure.in46
-rw-r--r--src/H5E.c18
-rw-r--r--src/H5config.h.in7
-rw-r--r--src/H5private.h1
5 files changed, 222 insertions, 3 deletions
diff --git a/configure b/configure
index 5525439..bc4a442 100755
--- a/configure
+++ b/configure
@@ -30855,7 +30855,7 @@ done
-for ac_func in signal snprintf vsnprintf strdup system waitpid
+for ac_func in signal snprintf vasprintf strdup system waitpid
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -30931,6 +30931,157 @@ fi
done
+
+for ac_func in vsnprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+char (*f) ();
+
+#ifdef F77_DUMMY_MAIN
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+f = $ac_func;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ echo "$as_me:$LINENO: checking if vsnprintf returns correct value" >&5
+echo $ECHO_N "checking if vsnprintf returns correct value... $ECHO_C" >&6
+
+ if test "${hdf5_cv_vsnprintf_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5
+echo "$as_me: error: cannot run test program while cross compiling" >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+int test_vsnprintf(const char *fmt,...)
+{
+ va_list ap;
+ char *s = malloc(16);
+ int ret;
+
+ va_start(ap, fmt);
+ ret=vsnprintf(s,16,"%s",ap);
+ va_end(ap);
+
+ return(ret==15 ? 1 : 0);
+}
+
+int main(void)
+{
+ exit(test_vsnprintf("%s","A string that is longer than 16 characters"));
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ hdf5_cv_vsnprintf_works=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+( exit $ac_status )
+hdf5_cv_vsnprintf_works=no
+fi
+rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+
+ if test ${hdf5_cv_vsnprintf_works} = "yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define VSNPRINTF_WORKS 1
+_ACEOF
+
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+fi
+done
+
+
echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
if test "${ac_cv_prog_cc_stdc+set}" = set; then
diff --git a/configure.in b/configure.in
index 0725202..09ae750 100644
--- a/configure.in
+++ b/configure.in
@@ -1644,7 +1644,51 @@ dnl Check for functions.
dnl
AC_CHECK_FUNCS(fork frexpf frexpl gethostname getpwuid getrusage)
AC_CHECK_FUNCS(BSDgettimeofday longjmp setsysinfo sigaction)
-AC_CHECK_FUNCS(signal snprintf vsnprintf strdup system waitpid)
+AC_CHECK_FUNCS(signal snprintf vasprintf strdup system waitpid)
+
+dnl Check for vsnprintf() separately, so we can detect situations where it
+dnl doesn't return the correct size for formatted strings that are too large
+dnl for the buffer provided
+AC_CHECK_FUNCS(vsnprintf,
+
+ dnl Check if vsnprintf() returns correct size for strings that don't fit
+ dnl into the size allowed. If vsnprintf() works correctly on this platform,
+ dnl it should return a value larger than 15 for the test below
+ AC_MSG_CHECKING([if vsnprintf returns correct value])
+
+ AC_CACHE_VAL([hdf5_cv_vsnprintf_works],
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+int test_vsnprintf(const char *fmt,...)
+{
+ va_list ap;
+ char *s = malloc(16);
+ int ret;
+
+ va_start(ap, fmt);
+ ret=vsnprintf(s,16,"%s",ap);
+ va_end(ap);
+
+ return(ret==15 ? 1 : 0);
+}
+
+int main(void)
+{
+ exit(test_vsnprintf("%s","A string that is longer than 16 characters"));
+}
+ ],[hdf5_cv_vsnprintf_works=yes],[hdf5_cv_vsnprintf_works=no],))
+
+ if test ${hdf5_cv_vsnprintf_works} = "yes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([VSNPRINTF_WORKS], [1],
+ [Define if vsnprintf() returns the correct value for formatted strings that don't fit into size allowed])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ,)
dnl ----------------------------------------------------------------------
dnl Check compiler characteristics
diff --git a/src/H5E.c b/src/H5E.c
index f55a92b..31d212f 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -1513,13 +1513,24 @@ H5Epush_stack(hid_t err_stack, const char *file, const char *func, unsigned line
/* Format the description */
va_start(ap, fmt);
+#ifdef H5_HAVE_VASPRINTF
+ /* Use the vasprintf() routine, since it does what we're trying to do below */
+ if(HDvasprintf(&tmp,fmt,ap)<0)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+#else /* H5_HAVE_VASPRINTF */
/* Allocate space for the formatted description buffer */
tmp_len=128;
if((tmp=H5MM_malloc((size_t)tmp_len))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* If the description doesn't fit into the initial buffer size, allocate more space and try again */
- while((desc_len=HDvsnprintf(tmp, (size_t)tmp_len, fmt, ap))>tmp_len) {
+ while((desc_len=HDvsnprintf(tmp, (size_t)tmp_len, fmt, ap))
+#ifdef H5_VSNPRINTF_WORKS
+ >
+#else /* H5_VSNPRINTF_WORKS */
+ >=
+#endif /* H5_VSNPRINTF_WORKS */
+ (tmp_len-1)) {
/* shutdown & restart the va_list */
va_end(ap);
va_start(ap, fmt);
@@ -1528,10 +1539,15 @@ H5Epush_stack(hid_t err_stack, const char *file, const char *func, unsigned line
H5MM_xfree(tmp);
/* Allocate a description of the appropriate length */
+#ifdef H5_VSNPRINTF_WORKS
tmp_len = desc_len+1;
+#else /* H5_VSNPRINTF_WORKS */
+ tmp_len = 2 * desc_len;
+#endif /* H5_VSNPRINTF_WORKS */
if((tmp=H5MM_malloc((size_t)tmp_len))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end while */
+#endif /* H5_HAVE_VASPRINTF */
va_end(ap);
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 6edc4fd..ab57f34 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -366,6 +366,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
@@ -553,6 +556,10 @@
correct precision. */
#undef ULLONG_TO_LDOUBLE_PRECISION_WORKS
+/* Define if vsnprintf() returns the correct value for formatted strings that
+ don't fit into size allowed */
+#undef VSNPRINTF_WORKS
+
/* Define if the HDF5 v1.6 compatibility functions are to be compiled in */
#undef WANT_H5_V1_6_COMPAT
diff --git a/src/H5private.h b/src/H5private.h
index fe4cbaa..95694c6 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -838,6 +838,7 @@ H5_DLL int64_t HDstrtoll (const char *s, const char **rest, int base);
#define HDva_arg(A,T) va_arg(A,T)
#define HDva_end(A) va_end(A)
#define HDva_start(A,P) va_start(A,P)
+#define HDvasprintf(RET,FMT,A) vasprintf(RET,FMT,A)
#define HDvfprintf(F,FMT,A) vfprintf(F,FMT,A)
#define HDvprintf(FMT,A) vprintf(FMT,A)
#define HDvsprintf(S,FMT,A) vsprintf(S,FMT,A)