diff options
-rwxr-xr-x | configure | 153 | ||||
-rw-r--r-- | configure.in | 46 | ||||
-rw-r--r-- | src/H5E.c | 18 | ||||
-rw-r--r-- | src/H5config.h.in | 7 | ||||
-rw-r--r-- | src/H5private.h | 1 |
5 files changed, 222 insertions, 3 deletions
@@ -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 @@ -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) |