Hi folks, please test the attached, it works for me on Fedora, but need to verify at least BSD, Solaris, etc. mingw remains special-case so it shouldn't be affected. This should force off_t_fmt to "ldd" in the cases Stefan observed.
Notably, it might not do the right thing with respect to strictness until we cover a particular c compiler in APR_TRY_COMPILE_NO_WARNING(). The mismatched int type assignments should crack under most any compiler, but mismatched printf formatting might not. APR_CHECK_TYPES_FMT_COMPATIBLE() uses that logic to perform a cross-platform compile torture test against our [s]size_t/off_t types, in place of the very peculiar APR_CHECK_TYPES_COMPATIBLE() which didn't appear to be portable beyond gcc at all, and was much too tolerant of language warnings. I personally think it should be a little more robust about checking that strtoll/_strtoll/_strtoq is available and appropriate and drop more of the apr_int64_t assumptions around off_t handling, but that was going a little too far off in the weeds. TIA for your reviews and feedback, Bill
Index: build/apr_common.m4 =================================================================== --- build/apr_common.m4 (revision 1855775) +++ build/apr_common.m4 (working copy) @@ -511,9 +511,9 @@ [int main(int argc, const char *const *argv) {] [[$2]] [ return 0; }] - )], - [$3], [$4]) - CFLAGS=$apr_save_CFLAGS + )], [CFLAGS=$apr_save_CFLAGS +$3], [CFLAGS=$apr_save_CFLAGS +$4]) ]) dnl @@ -975,11 +975,35 @@ ]) dnl +dnl APR_CHECK_TYPES_COMPATIBLE(TYPE-1, TYPE-2, FMT-TAG, +dnl [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +dnl +dnl Try to determine whether two types are the same and accept the given +dnl printf formatter (bare token, e.g. literal d, ld, etc). +dnl +AC_DEFUN([APR_CHECK_TYPES_FMT_COMPATIBLE], [ +define([apr_cvname], apr_cv_typematch_[]translit([$1], [ ], [_])_[]translit([$2], [ ], [_])_[][$3]) +AC_CACHE_CHECK([whether $1 and $2 use fmt %$3], apr_cvname, [ +APR_TRY_COMPILE_NO_WARNING([#include <sys/types.h> +#include <stdio.h>], [ + $1 chk1, *ptr1; + $2 chk2, *ptr2 = &chk1; + ptr1 = &chk2; + *ptr1 = *ptr2 = 0; + printf("%$3 %$3", chk1, chk2); +], [apr_cvname=yes +$4], [apr_cvname=no +$5])]) +]) + +dnl dnl APR_CHECK_TYPES_COMPATIBLE(TYPE-1, TYPE-2, [ACTION-IF-TRUE]) dnl dnl Try to determine whether two types are the same. Only works dnl for gcc and icc. dnl +dnl @deprecated @see APR_CHECK_TYPES_FMT_COMPATIBLE +dnl AC_DEFUN([APR_CHECK_TYPES_COMPATIBLE], [ define([apr_cvname], apr_cv_typematch_[]translit([$1], [ ], [_])_[]translit([$2], [ ], [_])) AC_CACHE_CHECK([whether $1 and $2 are the same], apr_cvname, [ Index: configure.in =================================================================== --- configure.in (revision 1855775) +++ configure.in (working copy) @@ -1768,13 +1768,17 @@ ;; esac -APR_CHECK_TYPES_COMPATIBLE(ssize_t, int, [ssize_t_fmt="d"]) -APR_CHECK_TYPES_COMPATIBLE(ssize_t, long, [ssize_t_fmt="ld"]) -APR_CHECK_TYPES_COMPATIBLE(size_t, unsigned int, [size_t_fmt="u"]) -APR_CHECK_TYPES_COMPATIBLE(size_t, unsigned long, [size_t_fmt="lu"]) +dnl I would expect much of the above to go away with new compile test +APR_CHECK_TYPES_FMT_COMPATIBLE(ssize_t, int, d, [ssize_t_fmt="d"], [ +APR_CHECK_TYPES_FMT_COMPATIBLE(ssize_t, long, ld, [ssize_t_fmt="ld"]) +]) +APR_CHECK_TYPES_FMT_COMPATIBLE(size_t, unsigned int, u, [size_t_fmt="u"], [ +APR_CHECK_TYPES_FMT_COMPATIBLE(size_t, unsigned long, lu, [size_t_fmt="lu"]) +]) APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], ssize_t, 8) +dnl the else cases below should no longer occur; AC_MSG_CHECKING([which format to use for apr_ssize_t]) if test -n "$ssize_t_fmt"; then AC_MSG_RESULT(%$ssize_t_fmt) @@ -1792,6 +1796,7 @@ APR_CHECK_SIZEOF_EXTENDED([#include <stddef.h>], size_t, 8) +# else cases below should no longer occur; AC_MSG_CHECKING([which format to use for apr_size_t]) if test -n "$size_t_fmt"; then AC_MSG_RESULT(%$size_t_fmt) @@ -1846,22 +1851,25 @@ off_t_strfn='strtol' off_t_size="$ac_cv_sizeof_long" elif test "$ac_cv_type_off_t" = "yes"; then + # off_t is more commonly a long than an int; prefer that case + # where int and long are the same size and interchangable. off_t_value=off_t off_t_size="$ac_cv_sizeof_off_t" - # off_t is more commonly a long than an int; prefer that case - # where int and long are the same size. - if test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long"; then - off_t_fmt='#define APR_OFF_T_FMT "ld"' + APR_CHECK_TYPES_FMT_COMPATIBLE(off_t, long, ld, [ + off_t_fmt="#define APR_OFF_T_FMT \"ld\"" off_t_strfn='strtol' - elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_int"; then - off_t_fmt='#define APR_OFF_T_FMT "d"' + ], [ + APR_CHECK_TYPES_FMT_COMPATIBLE(off_t, int, d, [ + off_t_fmt="#define APR_OFF_T_FMT \"d\"" off_t_strfn='strtoi' - elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long_long"; then - off_t_fmt='#define APR_OFF_T_FMT APR_INT64_T_FMT' + ], [ + APR_CHECK_TYPES_FMT_COMPATIBLE(off_t, long long, lld, [ + off_t_fmt="#define APR_OFF_T_FMT \"lld\"" off_t_strfn='apr_strtoi64' - else - AC_ERROR([could not determine the size of off_t]) - fi + ], [ + APR_CHECK_TYPES_FMT_COMPATIBLE(off_t, $int64_value, I64d, [ + off_t_fmt="#define APR_OFF_T_FMT APR_INT64_T_FMT" + off_t_strfn='apr_strtoi64'], [ # Per OS tuning... case $host in *-mingw*) @@ -1870,7 +1878,11 @@ off_t_strfn='_strtoi64' off_t_size=8 ;; + *) + AC_ERROR([could not determine the size of off_t]) + ;; esac + ])])])]) else # Fallback on int off_t_value=int