bug-gnulib
[Top][All Lists]
Advanced

[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;
  }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]