+2007-11-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don't insist on 'long long int' support in the preprocessor. It
+ breaks too many things. For example, PRIdMAX still uses a 'long
+ long int' format with the latest Sun compiler, even though
+ HAVE_LONG_LONG_INT isn't defined due to that compiler's
+ preprocessor problem. This causes the latest coreutils to dump
+ core on Solaris 10 sparc with the Sun C compiler.
+ Instead, fix the 2007-10-16 problem in a different way, by evaluating
+ the troublesome expressions at configure-time, not at #if-time.
+ * m4/longlong.m4 (_AC_TYPE_LONG_LONG_SNIPPET): Don't test the
+ preprocessor.
+ * m4/inttypes.m4 (gl_INTTYPES_H): Move the #if checks into
+ compile-time C checks, done at 'configure'-time.
+ (gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION): New macro.
+ * modules/inttypes (Makefile): Substitute the new symbols that
+ gl_INTTYPES_H now generates.
+ * lib/inttypes.in.h: Don't use constants wider than 'long' in #if.
+
2007-11-12 Bruno Haible <bruno@clisp.org>
Tests for Unicode character classification functions.
# endif
# endif
# ifdef INT64_MAX
-# if INT64_MAX == LONG_MAX
+# if @INT64_MAX_EQ_LONG_MAX@
# define _PRI64_PREFIX "l"
# elif defined _MSC_VER || defined __MINGW32__
# define _PRI64_PREFIX "I64"
# endif
# endif
# ifdef UINT64_MAX
-# if UINT64_MAX == ULONG_MAX
+# if @UINT64_MAX_EQ_ULONG_MAX@
# define _PRIu64_PREFIX "l"
# elif defined _MSC_VER || defined __MINGW32__
# define _PRIu64_PREFIX "I64"
# if !defined PRIdMAX || @PRI_MACROS_BROKEN@
# undef PRIdMAX
-# if INTMAX_MAX > INT32_MAX
+# if @INT32_MAX_LT_INTMAX_MAX@
# define PRIdMAX PRId64
# else
# define PRIdMAX "ld"
# endif
# if !defined PRIiMAX || @PRI_MACROS_BROKEN@
# undef PRIiMAX
-# if INTMAX_MAX > INT32_MAX
+# if @INT32_MAX_LT_INTMAX_MAX@
# define PRIiMAX PRIi64
# else
# define PRIiMAX "li"
# endif
# if !defined PRIoMAX || @PRI_MACROS_BROKEN@
# undef PRIoMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define PRIoMAX PRIo64
# else
# define PRIoMAX "lo"
# endif
# if !defined PRIuMAX || @PRI_MACROS_BROKEN@
# undef PRIuMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define PRIuMAX PRIu64
# else
# define PRIuMAX "lu"
# endif
# if !defined PRIxMAX || @PRI_MACROS_BROKEN@
# undef PRIxMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define PRIxMAX PRIx64
# else
# define PRIxMAX "lx"
# endif
# if !defined PRIXMAX || @PRI_MACROS_BROKEN@
# undef PRIXMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define PRIXMAX PRIX64
# else
# define PRIXMAX "lX"
# endif
# endif
# ifdef INT64_MAX
-# if INT64_MAX == LONG_MAX
+# if @INT64_MAX_EQ_LONG_MAX@
# define _SCN64_PREFIX "l"
# elif defined _MSC_VER || defined __MINGW32__
# define _SCN64_PREFIX "I64"
# endif
# endif
# ifdef UINT64_MAX
-# if UINT64_MAX == ULONG_MAX
+# if @UINT64_MAX_EQ_ULONG_MAX@
# define _SCNu64_PREFIX "l"
# elif defined _MSC_VER || defined __MINGW32__
# define _SCNu64_PREFIX "I64"
# if !defined SCNdMAX || @PRI_MACROS_BROKEN@
# undef SCNdMAX
-# if INTMAX_MAX > INT32_MAX
+# if @INT32_MAX_LT_INTMAX_MAX@
# define SCNdMAX SCNd64
# else
# define SCNdMAX "ld"
# endif
# if !defined SCNiMAX || @PRI_MACROS_BROKEN@
# undef SCNiMAX
-# if INTMAX_MAX > INT32_MAX
+# if @INT32_MAX_LT_INTMAX_MAX@
# define SCNiMAX SCNi64
# else
# define SCNiMAX "li"
# endif
# if !defined SCNoMAX || @PRI_MACROS_BROKEN@
# undef SCNoMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define SCNoMAX SCNo64
# else
# define SCNoMAX "lo"
# endif
# if !defined SCNuMAX || @PRI_MACROS_BROKEN@
# undef SCNuMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define SCNuMAX SCNu64
# else
# define SCNuMAX "lu"
# endif
# if !defined SCNxMAX || @PRI_MACROS_BROKEN@
# undef SCNxMAX
-# if UINTMAX_MAX > UINT32_MAX
+# if @UINT32_MAX_LT_UINTMAX_MAX@
# define SCNxMAX SCNx64
# else
# define SCNxMAX "lx"
HAVE_DECL_STRTOUMAX=0
fi
+ gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+ [INT32_MAX_LT_INTMAX_MAX],
+ [defined INT32_MAX && defined INTMAX_MAX],
+ [INT32_MAX < INTMAX_MAX],
+ [sizeof (int) < sizeof (long long int)])
+ gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+ [INT64_MAX_EQ_LONG_MAX],
+ [defined INT64_MAX],
+ [INT64_MAX == LONG_MAX],
+ [sizeof (long long int) == sizeof (long int)])
+ gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+ [UINT32_MAX_LT_UINTMAX_MAX],
+ [defined UINT32_MAX && defined UINTMAX_MAX],
+ [UINT32_MAX < UINTMAX_MAX],
+ [sizeof (unsigned int) < sizeof (unsigned long long int)])
+ gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+ [UINT64_MAX_EQ_ULONG_MAX],
+ [defined UINT64_MAX],
+ [UINT64_MAX == ULONG_MAX],
+ [sizeof (unsigned long long int) == sizeof (unsigned long int)])
+
INTTYPES_H='inttypes.h'
fi
AC_SUBST(INTTYPES_H)
])
+# Define the symbol $1 to be 1 if the condition is true, 0 otherwise.
+# If $2 is true, the condition is $3; otherwise if long long int is supported
+# approximate the condition with $4; otherwise, assume the condition is false.
+# The condition should work on all C99 platforms; the approximations should be
+# good enough to work on all practical pre-C99 platforms.
+# $2 is evaluated by the C preprocessor, $3 and $4 as compile-time constants.
+AC_DEFUN([gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION],
+[
+ AC_CACHE_CHECK([whether $3],
+ [gl_cv_test_$1],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[/* Work also in C++ mode. */
+ #define __STDC_LIMIT_MACROS 1
+
+ /* Work if build is not clean. */
+ #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H
+
+ #include <limits.h>
+ #if HAVE_STDINT_H
+ #include <stdint.h>
+ #endif
+
+ #if $2
+ #define CONDITION ($3)
+ #elif HAVE_LONG_LONG_INT
+ #define CONDITION ($4)
+ #else
+ #define CONDITION 0
+ #endif
+ int test[CONDITION ? 1 : -1];]])],
+ [gl_cv_test_$1=yes],
+ [gl_cv_test_$1=no])])
+ if test $gl_cv_test_$1 = yes; then
+ $1=1;
+ else
+ $1=0;
+ fi
+ AC_SUBST([$1])
+])
+
AC_DEFUN([gl_INTTYPES_MODULE_INDICATOR],
[
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
[
AC_LANG_PROGRAM(
- [[/* Test preprocessor. */
- #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- error in preprocessor;
- #endif
- #if ! (18446744073709551615ULL <= -1ull)
- error in preprocessor;
- #endif
+ [[/* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
/* Test literals. */
long long int ll = 9223372036854775807ll;
long long int nll = -9223372036854775807LL;
-e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \
-e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \
-e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \
+ -e 's/@''INT32_MAX_LT_INTMAX_MAX''@/$(INT32_MAX_LT_INTMAX_MAX)/g' \
+ -e 's/@''INT64_MAX_EQ_LONG_MAX''@/$(INT64_MAX_EQ_LONG_MAX)/g' \
+ -e 's/@''UINT32_MAX_LT_UINTMAX_MAX''@/$(UINT32_MAX_LT_UINTMAX_MAX)/g' \
+ -e 's/@''UINT64_MAX_EQ_ULONG_MAX''@/$(UINT64_MAX_EQ_ULONG_MAX)/g' \
-e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
< $(srcdir)/inttypes.in.h; \
} > $@-t