Joe Orton wrote: > On Sun, Jul 08, 2007 at 12:38:33AM -0300, Davi Arnaut wrote: >> I think we could improve the (autoconf) format detection by: >> >> 1) Using __builtin_types_compatible_p (available since gcc-3.1) > > This looks like a great idea. > >> 2) First checking if the ssize_t type size is equal to long size, which >> seems true on most systems. > > Not so sure I'd mess with this. At least 32-bit Linux really does use > an int for ssize_t.
Ok. > But the most important thing here is that the qualifier used in the > format string really does match the integer size. Where int and long > are the same size, the effect of an incorrect %d or %ld choice is only a > compiler warning. Patch attached, looks good? -- Davi Arnaut
Index: apr/build/apr_common.m4 =================================================================== --- apr.orig/build/apr_common.m4 +++ apr/build/apr_common.m4 @@ -959,3 +959,30 @@ fi AC_SUBST(MKDEP) ]) + +dnl +dnl APR_CHECK_TYPES_COMPATIBLE(TYPE-1, TYPE-2) +dnl +dnl Try to determine whether two types are the same +dnl +AC_DEFUN([APR_CHECK_TYPES_COMPATIBLE], [ +AC_MSG_CHECKING(whether $1 and $2 are the same) +AC_TRY_COMPILE(AC_INCLUDES_DEFAULT, [ + __builtin_types_compatible_p($1, $2); +], [apr_types_compile=yes], [apr_types_compile=no]) +AC_RUN_IFELSE([AC_LANG_SOURCE([AC_INCLUDES_DEFAULT +int main () +{ + return !__builtin_types_compatible_p($1, $2); +}])], [apr_types_run=yes], [apr_types_run=no], [apr_types_run=no]) +if test $apr_types_compile = yes; then + if test $apr_types_run = yes; then + apr_types_compatible=yes + else + apr_types_compatible=no + fi +else + apr_types_compatible=unknown +fi +AC_MSG_RESULT([$apr_types_compatible]) +]) Index: apr/configure.in =================================================================== --- apr.orig/configure.in +++ apr/configure.in @@ -1330,26 +1330,99 @@ else socklen_t_value="int" fi +APR_CHECK_TYPES_COMPATIBLE(ssize_t, int) +if test "$apr_types_compatible" = yes; then + ssize_t_fmt="d" +fi + +APR_CHECK_TYPES_COMPATIBLE(ssize_t, long) +if test "$apr_types_compatible" = yes; then + ssize_t_fmt="ld" +fi + +APR_CHECK_TYPES_COMPATIBLE(size_t, unsigned int) +if test "$apr_types_compatible" = yes; then + size_t_fmt="u" +fi + +APR_CHECK_TYPES_COMPATIBLE(size_t, unsigned long) +if test "$apr_types_compatible" = yes; then + size_t_fmt="lu" +fi + +# Basically, we have tried to figure out the correct format strings +# for APR types which vary between platforms, but we don't always get +# it right. If you find that we don't get it right for your platform, +# you can override our decision below. +case $host in + s390*linux*) + # uniquely, the 31-bit Linux/s390 uses "unsigned long int" + # for size_t rather than "unsigned int": + size_t_fmt="lu" + ssize_t_fmt="ld" + ;; + *-os2*) + size_t_fmt="lu" + ;; + *-solaris*) + pid_t_fmt="ld" + ;; + *aix4*|*aix5*) + ssize_t_fmt="ld" + size_t_fmt="ld" + ;; + *beos*) + ssize_t_fmt="ld" + size_t_fmt="ld" + ;; + *apple-darwin*) + osver=`uname -r` + case $osver in + [[0-7]].*) + ssize_t_fmt="d" + ;; + *) + ssize_t_fmt="ld" + ;; + esac + size_t_fmt="lu" + ;; +esac + APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], ssize_t, 8) -if test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_int"; then - ssize_t_fmt='#define APR_SSIZE_T_FMT "d"' +AC_MSG_CHECKING([which format to use for apr_ssize_t]) +if test -n "$ssize_t_fmt"; then + AC_MSG_RESULT(%$ssize_t_fmt) +elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_int"; then + ssize_t_fmt="d" + AC_MSG_RESULT(%d) elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_long"; then - ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"' + ssize_t_fmt="ld" + AC_MSG_RESULT(%ld) else - ssize_t_fmt='#error Can not determine the proper size for ssize_t' + AC_ERROR([could not determine the proper format for apr_ssize_t]) fi +ssize_t_fmt="#define APR_SSIZE_T_FMT \"$ssize_t_fmt\"" + APR_CHECK_SIZEOF_EXTENDED([#include <stddef.h>], size_t, 8) -if test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_int"; then - size_t_fmt='#define APR_SIZE_T_FMT "d"' +AC_MSG_CHECKING([which format to use for apr_size_t]) +if test -n "$size_t_fmt"; then + AC_MSG_RESULT(%$size_t_fmt) +elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_int"; then + size_t_fmt="d" + AC_MSG_RESULT(%d) elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_long"; then - size_t_fmt='#define APR_SIZE_T_FMT "ld"' + size_t_fmt="ld" + AC_MSG_RESULT(%ld) else - size_t_fmt='#error Can not determine the proper size for size_t' + AC_ERROR([could not determine the proper format for apr_size_t]) fi +size_t_fmt="#define APR_SIZE_T_FMT \"$size_t_fmt\"" + APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], off_t, 8) if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then @@ -1420,45 +1493,6 @@ else bigendian=0 fi -# Basically, we have tried to figure out the correct format strings -# for APR types which vary between platforms, but we don't always get -# it right. If you find that we don't get it right for your platform, -# you can override our decision below. -case $host in - s390*linux*) - # uniquely, the 31-bit Linux/s390 uses "unsigned long int" - # for size_t rather than "unsigned int": - size_t_fmt='#define APR_SIZE_T_FMT "lu"' - ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"' - ;; - *-os2*) - size_t_fmt='#define APR_SIZE_T_FMT "lu"' - ;; - *-solaris*) - pid_t_fmt='#define APR_PID_T_FMT "ld"' - ;; - *aix4*|*aix5*) - ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"' - size_t_fmt='#define APR_SIZE_T_FMT "ld"' - ;; - *beos*) - ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"' - size_t_fmt='#define APR_SIZE_T_FMT "ld"' - ;; - *apple-darwin*) - osver=`uname -r` - case $osver in - [[0-7]].*) - ssize_t_fmt='#define APR_SSIZE_T_FMT "d"' - ;; - *) - ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"' - ;; - esac - size_t_fmt='#define APR_SIZE_T_FMT "lu"' - ;; -esac - APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h> #include <sys/uio.h>],struct iovec,0) if test "$ac_cv_sizeof_struct_iovec" = "0"; then