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