]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
strtoull: Work around a bug on native Windows and Minix.
authorBruno Haible <bruno@clisp.org>
Fri, 2 Apr 2021 18:14:28 +0000 (20:14 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 2 Apr 2021 18:14:28 +0000 (20:14 +0200)
* lib/stdlib.in.h (strtoull): Override if REPLACE_STRTOULL is 1.
* m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Initialize REPLACE_STRTOULL.
* m4/strtoull.m4 (gl_FUNC_STRTOULL): Test whether strtoull works. Set
REPLACE_STRTOULL.
* modules/stdlib (Makefile.am): Substitute REPLACE_STRTOULL.
* modules/strtoull (configure.ac): Test REPLACE_STRTOULL.
* tests/test-strtoull.c (main): Add tests of hexadecimal integer syntax.
* doc/posix-functions/strtoull.texi: Mention the bug.

ChangeLog
doc/posix-functions/strtoull.texi
lib/stdlib.in.h
m4/stdlib_h.m4
m4/strtoull.m4
modules/stdlib
modules/strtoull
tests/test-strtoull.c

index 9ce3baeb4f65836404111a7de162421b77113b17..5d752aba3f668ab4e587248d613e906a3788900b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2021-04-02  Bruno Haible  <bruno@clisp.org>
+
+       strtoull: Work around a bug on native Windows and Minix.
+       * lib/stdlib.in.h (strtoull): Override if REPLACE_STRTOULL is 1.
+       * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Initialize REPLACE_STRTOULL.
+       * m4/strtoull.m4 (gl_FUNC_STRTOULL): Test whether strtoull works. Set
+       REPLACE_STRTOULL.
+       * modules/stdlib (Makefile.am): Substitute REPLACE_STRTOULL.
+       * modules/strtoull (configure.ac): Test REPLACE_STRTOULL.
+       * tests/test-strtoull.c (main): Add tests of hexadecimal integer syntax.
+       * doc/posix-functions/strtoull.texi: Mention the bug.
+
 2021-04-02  Bruno Haible  <bruno@clisp.org>
 
        strtoul: Work around a bug on native Windows and Minix.
index 2057fc7b9764c5d893504938d10fcbe67a12f958..68ede343e1732230370c617834e6d9bc69666a78 100644 (file)
@@ -11,6 +11,10 @@ Portability problems fixed by Gnulib:
 @item
 This function is missing on some platforms:
 HP-UX 11.11, MSVC 9.
+@item
+This function does not parse the leading @samp{0} when the input string is
+@code{"0x"} and the base is 16 or 0 on some platforms:
+Minix 3.3, mingw, MSVC 14.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 0a377c075550816e9bd74c83d810a3d153719ff6..050636245b5af792a12f64675e0ade3c9240fcc2 100644 (file)
@@ -1278,15 +1278,29 @@ _GL_WARN_ON_USE (strtoul, "strtoul is unportable - "
    stored in *ENDPTR.
    Upon overflow, the return value is ULLONG_MAX, and errno is set to
    ERANGE.  */
-# if !@HAVE_STRTOULL@
+# if @REPLACE_STRTOULL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define strtoull rpl_strtoull
+#  endif
+#  define GNULIB_defined_strtoull_function 1
+_GL_FUNCDECL_RPL (strtoull, unsigned long long,
+                  (const char *restrict string, char **restrict endptr,
+                   int base)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoull, unsigned long long,
+                  (const char *restrict string, char **restrict endptr,
+                   int base));
+# else
+#  if !@HAVE_STRTOULL@
 _GL_FUNCDECL_SYS (strtoull, unsigned long long,
                   (const char *restrict string, char **restrict endptr,
                    int base)
                   _GL_ARG_NONNULL ((1)));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (strtoull, unsigned long long,
                   (const char *restrict string, char **restrict endptr,
                    int base));
+# endif
 _GL_CXXALIASWARN (strtoull);
 #elif defined GNULIB_POSIXCHECK
 # undef strtoull
index 5895586a23fee64373ad6ed7a3249e4aa00eca22..652ba86ffd26c609d5e7fe36e53c97139c1945bf 100644 (file)
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 56
+# stdlib_h.m4 serial 57
 dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -168,6 +168,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   REPLACE_STRTOD=0;          AC_SUBST([REPLACE_STRTOD])
   REPLACE_STRTOLD=0;         AC_SUBST([REPLACE_STRTOLD])
   REPLACE_STRTOUL=0;         AC_SUBST([REPLACE_STRTOUL])
+  REPLACE_STRTOULL=0;        AC_SUBST([REPLACE_STRTOULL])
   REPLACE_UNSETENV=0;        AC_SUBST([REPLACE_UNSETENV])
   REPLACE_WCTOMB=0;          AC_SUBST([REPLACE_WCTOMB])
 ])
index 88867ee4e58ace490fa866c2db5a7a0cb081d3c7..41178cc6824a41c77193290834269696b55813b6 100644 (file)
@@ -1,4 +1,4 @@
-# strtoull.m4 serial 8
+# strtoull.m4 serial 9
 dnl Copyright (C) 2002, 2004, 2006, 2008-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -7,8 +7,40 @@ dnl with or without modifications, as long as this notice is preserved.
 AC_DEFUN([gl_FUNC_STRTOULL],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
   AC_CHECK_FUNCS([strtoull])
-  if test $ac_cv_func_strtoull = no; then
+  if test $ac_cv_func_strtoull = yes; then
+    AC_CACHE_CHECK([whether strtoull works],
+      [gl_cv_func_strtoull_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <stdlib.h>]],
+            [[int result = 0;
+              char *term;
+              /* This test fails on Minix and native Windows.  */
+              {
+                const char input[] = "0x";
+                (void) strtoull (input, &term, 16);
+                if (term != input + 1)
+                  result |= 1;
+              }
+              return result;
+            ]])
+         ],
+         [gl_cv_func_strtoull_works=yes],
+         [gl_cv_func_strtoull_works=no],
+         [case "$host_os" in
+                    # Guess no on native Windows.
+            mingw*) gl_cv_func_strtoull_works="guessing no" ;;
+            *)      gl_cv_func_strtoull_works="$gl_cross_guess_normal" ;;
+          esac
+         ])
+    ])
+    case "$gl_cv_func_strtoull_works" in
+      *yes) ;;
+      *)    REPLACE_STRTOULL=1 ;;
+    esac
+  else
     HAVE_STRTOULL=0
   fi
 ])
index 998f44d2408f979b6516c28993fbcb82769720f5..4bd7a5c683347a796214f5fe035f12b9ac1ba8ed 100644 (file)
@@ -140,6 +140,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
              -e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \
              -e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \
+             -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \
              -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
              -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
index ff83b69af6d6467736a1310e0639549b7153bf7b..9b5895b5c7acc0148bddcff8ac66c3f8e798534d 100644 (file)
@@ -13,7 +13,7 @@ stdlib
 
 configure.ac:
 gl_FUNC_STRTOULL
-if test $HAVE_STRTOULL = 0; then
+if test $HAVE_STRTOULL = 0 || test $REPLACE_STRTOULL = 1; then
   AC_LIBOBJ([strtoull])
   gl_PREREQ_STRTOULL
 fi
index 8242d3caf5db8d52089ccf88847a929effb85de5..db7b37103842583c9ed382be07175236924d6cc2 100644 (file)
@@ -176,5 +176,67 @@ main (void)
     ASSERT (errno == 0);
   }
 
+  /* Hexadecimal integer syntax.  */
+  {
+    const char input[] = "0x2A";
+    char *ptr;
+    unsigned long long result;
+    errno = 0;
+    result = strtoull (input, &ptr, 10);
+    ASSERT (result == 0ULL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x2A";
+    char *ptr;
+    unsigned long long result;
+    errno = 0;
+    result = strtoull (input, &ptr, 16);
+    ASSERT (result == 42ULL);
+    ASSERT (ptr == input + 4);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x2A";
+    char *ptr;
+    unsigned long long result;
+    errno = 0;
+    result = strtoull (input, &ptr, 0);
+    ASSERT (result == 42ULL);
+    ASSERT (ptr == input + 4);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x";
+    char *ptr;
+    unsigned long long result;
+    errno = 0;
+    result = strtoull (input, &ptr, 10);
+    ASSERT (result == 0ULL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x";
+    char *ptr;
+    unsigned long long result;
+    errno = 0;
+    result = strtoull (input, &ptr, 16);
+    ASSERT (result == 0ULL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x";
+    char *ptr;
+    unsigned long long result;
+    errno = 0;
+    result = strtoull (input, &ptr, 0);
+    ASSERT (result == 0ULL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+
   return 0;
 }