[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
strtoimax: work around AIX 5.1 bug
From: |
Bruno Haible |
Subject: |
strtoimax: work around AIX 5.1 bug |
Date: |
Thu, 05 Jan 2012 18:50:20 +0100 |
User-agent: |
KMail/4.7.4 (Linux/3.1.0-1.2-desktop; KDE/4.7.4; x86_64; ; ) |
The strtoimax() on AIX supports only values in the 'int' range, although
intmax_t is really 'long long' (= 64-bit). This leads to a broken 'expr'
program in coreutils. Although AIX 5.1 is no longer among our focus,
I'm adding this workaround, because strtoimax() is a pretty basic function.
2012-01-05 Bruno Haible <address@hidden>
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.
*** doc/posix-functions/strtoimax.texi.orig Thu Jan 5 18:46:08 2012
--- doc/posix-functions/strtoimax.texi Thu Jan 5 18:45:21 2012
***************
*** 11,16 ****
--- 11,19 ----
@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:
*** lib/inttypes.in.h.orig Thu Jan 5 18:46:08 2012
--- lib/inttypes.in.h Thu Jan 5 18:45:56 2012
***************
*** 1079,1090 ****
#endif
#if @GNULIB_STRTOIMAX@
! # if address@hidden@
! # undef strtoimax
_GL_FUNCDECL_SYS (strtoimax, intmax_t,
(const char *, char **, int) _GL_ARG_NONNULL ((1)));
! # endif
_GL_CXXALIAS_SYS (strtoimax, intmax_t, (const char *, char **, int));
_GL_CXXALIASWARN (strtoimax);
#elif defined GNULIB_POSIXCHECK
# undef strtoimax
--- 1079,1100 ----
#endif
#if @GNULIB_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 address@hidden@
! # undef strtoimax
_GL_FUNCDECL_SYS (strtoimax, intmax_t,
(const char *, char **, int) _GL_ARG_NONNULL ((1)));
! # endif
_GL_CXXALIAS_SYS (strtoimax, intmax_t, (const char *, char **, int));
+ # endif
_GL_CXXALIASWARN (strtoimax);
#elif defined GNULIB_POSIXCHECK
# undef strtoimax
*** m4/inttypes.m4.orig Thu Jan 5 18:46:08 2012
--- m4/inttypes.m4 Thu Jan 5 18:45:21 2012
***************
*** 1,4 ****
! # inttypes.m4 serial 25
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,
--- 1,4 ----
! # 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,
***************
*** 147,152 ****
--- 147,153 ----
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])
*** m4/strtoimax.m4.orig Thu Jan 5 18:46:08 2012
--- m4/strtoimax.m4 Thu Jan 5 18:45:21 2012
***************
*** 1,4 ****
! # strtoimax.m4 serial 11
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,
--- 1,4 ----
! # 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,
***************
*** 14,19 ****
--- 14,71 ----
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.
*** modules/inttypes-incomplete.orig Thu Jan 5 18:46:08 2012
--- modules/inttypes-incomplete Thu Jan 5 18:45:21 2012
***************
*** 42,47 ****
--- 42,48 ----
-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' \
*** modules/strtoimax.orig Thu Jan 5 18:46:08 2012
--- modules/strtoimax Thu Jan 5 18:45:21 2012
***************
*** 3,20 ****
Files:
lib/strtoimax.c
- m4/longlong.m4
m4/strtoimax.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]
configure.ac:
gl_FUNC_STRTOIMAX
! if test $ac_cv_func_strtoimax = no; then
AC_LIBOBJ([strtoimax])
gl_PREREQ_STRTOIMAX
fi
--- 3,22 ----
Files:
lib/strtoimax.c
m4/strtoimax.m4
+ m4/stdint_h.m4
+ m4/inttypes_h.m4
+ m4/longlong.m4
Depends-on:
inttypes-incomplete
! 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 $HAVE_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then
AC_LIBOBJ([strtoimax])
gl_PREREQ_STRTOIMAX
fi
*** tests/test-strtoimax.c.orig Thu Jan 5 18:46:08 2012
--- tests/test-strtoimax.c Thu Jan 5 18:45:21 2012
***************
*** 144,148 ****
--- 144,181 ----
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;
}
- strtoimax: work around AIX 5.1 bug,
Bruno Haible <=