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

Reply via email to