+2012-01-05 Bruno Haible <bruno@clisp.org>
+
+ strtoimax: Work around AIX 5.1 bug.
+ * lib/inttypes.in.h (strtoimax): Allow overriding the system's
+ definition.
+ * m4/strtoimax.m4 (gl_FUNC_STRTOIMAX): Check against the AIX 5.1 bug.
+ Set HAVE_STRTOIMAX.
+ * m4/inttypes.m4 (gl_INTTYPES_H_DEFAULTS): Initialize
+ REPLACE_STRTOIMAX.
+ * modules/inttypes-incomplete (Makefile.am): Substitute
+ REPLACE_STRTOIMAX.
+ * modules/strtoimax (Files): Add m4/stdint_h.m4, m4/inttypes_h.m4.
+ (configure.ac): Test HAVE_STRTOIMAX, REPLACE_STRTOIMAX.
+ (Depends-on): Update conditions.
+ * tests/test-strtoimax.c (main): Add tests for large values.
+ * doc/posix-functions/strtoimax.texi: Mention the AIX 5.1 bug.
+
2012-01-05 Bruno Haible <bruno@clisp.org>
inttypes: Modernize.
@item
This function is missing on some platforms:
OpenBSD 3.8, Minix 3.1.8, AIX 4.3.2, IRIX 6.5, OSF/1 5.1, Solaris 9, MSVC 9, Interix 3.5.
+@item
+This function fails on valid input strings on some platforms:
+AIX 5.1.
@end itemize
Portability problems not fixed by Gnulib:
#endif
#if @GNULIB_STRTOIMAX@
-# if !@HAVE_DECL_STRTOIMAX@
-# undef strtoimax
+# if @REPLACE_STRTOIMAX@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strtoimax
+# define strtoimax rpl_strtoimax
+# endif
+_GL_FUNCDECL_RPL (strtoimax, intmax_t,
+ (const char *, char **, int) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoimax, intmax_t, (const char *, char **, int));
+# else
+# if !@HAVE_DECL_STRTOIMAX@
+# undef strtoimax
_GL_FUNCDECL_SYS (strtoimax, intmax_t,
(const char *, char **, int) _GL_ARG_NONNULL ((1)));
-# endif
+# endif
_GL_CXXALIAS_SYS (strtoimax, intmax_t, (const char *, char **, int));
+# endif
_GL_CXXALIASWARN (strtoimax);
#elif defined GNULIB_POSIXCHECK
# undef strtoimax
-# inttypes.m4 serial 25
+# inttypes.m4 serial 26
dnl Copyright (C) 2006-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
HAVE_DECL_IMAXDIV=1; AC_SUBST([HAVE_DECL_IMAXDIV])
HAVE_DECL_STRTOIMAX=1; AC_SUBST([HAVE_DECL_STRTOIMAX])
HAVE_DECL_STRTOUMAX=1; AC_SUBST([HAVE_DECL_STRTOUMAX])
+ REPLACE_STRTOIMAX=0; AC_SUBST([REPLACE_STRTOIMAX])
INT32_MAX_LT_INTMAX_MAX=1; AC_SUBST([INT32_MAX_LT_INTMAX_MAX])
INT64_MAX_EQ_LONG_MAX='defined _LP64'; AC_SUBST([INT64_MAX_EQ_LONG_MAX])
PRI_MACROS_BROKEN=0; AC_SUBST([PRI_MACROS_BROKEN])
-# strtoimax.m4 serial 11
+# strtoimax.m4 serial 12
dnl Copyright (C) 2002-2004, 2006, 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
if test "$ac_cv_have_decl_strtoimax" != yes; then
HAVE_DECL_STRTOIMAX=0
fi
+
+ if test $ac_cv_func_strtoimax = yes; then
+ HAVE_STRTOIMAX=1
+ dnl On AIX 5.1, strtoimax() fails for values outside the 'int' range.
+ AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether strtoimax works], [gl_cv_func_strtoimax],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+# include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+# include <inttypes.h>
+#endif
+int main ()
+{
+ const char *s = "4294967295";
+ char *p;
+ intmax_t res;
+ errno = 0;
+ res = strtoimax (s, &p, 10);
+ if (p != s + strlen (s))
+ return 1;
+ if (errno != 0)
+ return 2;
+ if (res != (intmax_t) 65535 * (intmax_t) 65537)
+ return 3;
+ return 0;
+}
+]])],
+ [gl_cv_func_strtoimax=yes],
+ [gl_cv_func_strtoimax=no],
+ [case "$host_os" in
+ # Guess no on AIX 5.
+ aix5*) gl_cv_func_strtoimax="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_strtoimax="guessing yes" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_strtoimax" in
+ *no) REPLACE_STRTOIMAX=1 ;;
+ esac
+ else
+ HAVE_STRTOIMAX=0
+ fi
])
# Prerequisites of lib/strtoimax.c.
-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/@''REPLACE_STRTOIMAX''@/$(REPLACE_STRTOIMAX)/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' \
Files:
lib/strtoimax.c
-m4/longlong.m4
m4/strtoimax.m4
+m4/stdint_h.m4
+m4/inttypes_h.m4
+m4/longlong.m4
Depends-on:
inttypes-incomplete
-verify [test $ac_cv_func_strtoimax = no]
-stdint [test $ac_cv_func_strtoimax = no]
-strtoll [test $ac_cv_func_strtoimax = no && test $ac_cv_type_long_long_int = yes]
+verify [test $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1]
+stdint [test $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1]
+strtoll [{ test $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes]
configure.ac:
gl_FUNC_STRTOIMAX
-if test $ac_cv_func_strtoimax = no; then
+if test $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then
AC_LIBOBJ([strtoimax])
gl_PREREQ_STRTOIMAX
fi
ASSERT (errno == 0);
}
+ /* Large integer values. */
+ {
+ const char input[] = "2147483647";
+ char *ptr;
+ intmax_t result;
+ errno = 0;
+ result = strtoimax (input, &ptr, 10);
+ ASSERT (result == 2147483647);
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "-2147483648";
+ char *ptr;
+ intmax_t result;
+ errno = 0;
+ result = strtoimax (input, &ptr, 10);
+ ASSERT (result == -2147483647 - 1);
+ ASSERT (ptr == input + 11);
+ ASSERT (errno == 0);
+ }
+ if (sizeof (intmax_t) > sizeof (int))
+ {
+ const char input[] = "4294967295";
+ char *ptr;
+ intmax_t result;
+ errno = 0;
+ result = strtoimax (input, &ptr, 10);
+ ASSERT (result == (intmax_t) 65535 * (intmax_t) 65537);
+ ASSERT (ptr == input + 10);
+ ASSERT (errno == 0);
+ }
+
return 0;
}