Hello,
  I noticed that the macro _AC_COMPUTE_INT_COMPILE calls
_AC_COMPILE_IFELSE with a "break" in a paramter.
As reported a few days ago, this can cause the macro
to leave some garbage files in current directory.

(The test suite wasn't able to catch this, because the
three calls of AC_CHECK_SIZEOF were aggregated.)

The attached patch fixes the problem.  Moreover, it is optimized,
so that the _AC_COMPILE_IFELSE is expanded only once.

I think I preserved all the fragile things, like ability to
handle maximum and minimum of types under the 2's complement
arithmetics (used by almost all today's machines).

The number of compilations needed is almost the same:
- for positive numbers, one less compilation is needed
- for 0 and -1, one more compilation is needed
- for numbers <= -2, the number is the same.

This is an advantage, since Autoconf uses it to detect sizeof
and alignof, ie. positive numbers.

OK to commit?

Stepan
2005-09-06  Stepan Kasal  <[EMAIL PROTECTED]>

        * lib/autoconf/general.m4 (_AC_COMPUTE_INT_COMPILE): Do not use
        "break" in the parameters to _AC_COMPILE_IFELSE; reorganize the
        code, so that _AC_COMPILE_IFELSE is called only once.

Index: lib/autoconf/general.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/lib/autoconf/general.m4,v
retrieving revision 1.885
diff -u -r1.885 general.m4
--- lib/autoconf/general.m4     6 Sep 2005 15:39:01 -0000       1.885
+++ lib/autoconf/general.m4     7 Sep 2005 11:21:15 -0000
@@ -2548,37 +2548,46 @@
 # Compute the integer EXPRESSION and store the result in the VARIABLE.
 # Works OK if cross compiling, but assumes twos-complement arithmetic.
 m4_define([_AC_COMPUTE_INT_COMPILE],
-[# Depending upon the size, compute the lo and hi bounds.
-_AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$3], [($1) >= 0])],
- [ac_lo=0 ac_mid=0
-  while :; do
-    _AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$3], [($1) <= $ac_mid])],
-                      [ac_hi=$ac_mid; break],
-                      [ac_lo=`expr $ac_mid + 1`
-                       if test $ac_lo -le $ac_mid; then
-                         ac_lo= ac_hi=
-                         break
-                       fi
-                       ac_mid=`expr 2 '*' $ac_mid + 1`])
-  done],
-[AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$3], [($1) < 0])],
- [ac_hi=-1 ac_mid=-1
-  while :; do
-    _AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$3], [($1) >= $ac_mid])],
-                      [ac_lo=$ac_mid; break],
-                      [ac_hi=`expr '(' $ac_mid ')' - 1`
-                       if test $ac_mid -le $ac_hi; then
-                         ac_lo= ac_hi=
-                         break
-                       fi
-                       ac_mid=`expr 2 '*' $ac_mid`])
-  done],
- [ac_lo= ac_hi=])])
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
-  _AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$3], [($1) <= $ac_mid])],
-                    [ac_hi=$ac_mid], [ac_lo=`expr '(' $ac_mid ')' + 1`])
+[# Compute the lo and hi bounds, then do a binary search between them:
+ac_mid=0 ac_lo= ac_hi= ac_pos=
+# Most of the time, ac_sign is <= or >=, but for the very first run, it is 
different:
+ac_sign=">"
+while :; do
+  _AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([$3], [($1) $ac_sign $ac_mid])],
+    [ac_res=y], [ac_res=n])
+  # Now deduce from the result of the above experiment:
+  # (ac_pos indicates whether the value is positive.)
+  case $ac_pos:$ac_lo:$ac_hi:$ac_res in
+    # If ac_pos is empty, this was the very first run:
+    :::*) ac_pos=$ac_res ac_sign='<=';; # ac_mid remains 0
+    # If both ac_lo and ac_hi are empty, this was the second run:
+    y:::n) ac_lo=1 ac_mid=1;; # ac_sign remains <=
+    n:::y) ac_hi=0 ac_mid=-1 ac_sign='>=';;
+    *:::*) # Contradicting results:
+       break;; # ac_lo is empty
+    # Positive value, ac_sign is <=, ac_hi is empty:
+    y:*::y) ac_hi=$ac_mid;;
+    y:*::n) ac_lo=`expr $ac_mid + 1`
+       AS_IF([test $ac_lo -le $ac_mid], [ac_lo=; break])dnl Overflow.
+       ac_mid=`expr 2 '*' $ac_mid + 1`
+       ;;
+    # Negative value (or zero), ac_sign is >=, ac_lo is empty:
+    n::*:y) ac_lo=$ac_mid;;
+    n::*:n) ac_hi=`expr '(' $ac_mid ')' - 1`
+       AS_IF([test $ac_mid -le $ac_hi], [ac_lo=; break])dnl Overflow.
+       ac_mid=`expr 2 '*' $ac_mid`
+       ;;
+    # Binary search, ac_sign is <=:
+    ?:*:*:y) ac_hi=$ac_mid;;
+    ?:*:*:n) ac_lo=`expr '(' $ac_mid ')' + 1`;;
+  esac
+  # If both ac_lo and ac_hi are now non-empty, we are performing binary search:
+  case $ac_lo:$ac_hi in
+    :* | *:) ;;
+    *) test x$ac_lo = x$ac_hi && break
+       ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+       ac_sign='<=' ;;
+  esac
 done
 case $ac_lo in
 ?*) $2=$ac_lo;;

Reply via email to