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

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

index 9a84589cbc078f08e08bab70f83a81297fed7bba..b47957457604ef242e7b590dd17bc4b73a443aa6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2021-04-02  Bruno Haible  <bruno@clisp.org>
+
+       strtoll: Work around a bug on native Windows and Minix.
+       * lib/stdlib.in.h (strtoll): Override if REPLACE_STRTOLL is 1.
+       * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Initialize REPLACE_STRTOLL.
+       * m4/strtoll.m4 (gl_FUNC_STRTOLL): Test whether strtoll works. Set
+       REPLACE_STRTOLL.
+       * modules/stdlib (Makefile.am): Substitute REPLACE_STRTOLL.
+       * modules/strtoll (configure.ac): Test REPLACE_STRTOLL.
+       * tests/test-strtoll.c (main): Add tests of hexadecimal integer syntax.
+       * doc/posix-functions/strtoll.texi: Mention the bug.
+
 2021-04-02  Bruno Haible  <bruno@clisp.org>
 
        strtol: Work around a bug on native Windows and Minix.
index 45a70350d7c279ca052c43f329922482bedaabbf..b507fc33c60c4b31c9da8ffec53a89c1dd877534 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 e2c461b59adaa0c949150a8bd69c550041659226..c07fd1f5d7bb99760e6f664cc0a794cc3ca11a12 100644 (file)
@@ -1252,15 +1252,29 @@ _GL_WARN_ON_USE (strtol, "strtol is unportable - "
    stored in *ENDPTR.
    Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set
    to ERANGE.  */
-# if !@HAVE_STRTOLL@
+# if @REPLACE_STRTOLL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define strtoll rpl_strtoll
+#  endif
+#  define GNULIB_defined_strtoll_function 1
+_GL_FUNCDECL_RPL (strtoll, long long,
+                  (const char *restrict string, char **restrict endptr,
+                   int base)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoll, long long,
+                  (const char *restrict string, char **restrict endptr,
+                   int base));
+# else
+#  if !@HAVE_STRTOLL@
 _GL_FUNCDECL_SYS (strtoll, long long,
                   (const char *restrict string, char **restrict endptr,
                    int base)
                   _GL_ARG_NONNULL ((1)));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (strtoll, long long,
                   (const char *restrict string, char **restrict endptr,
                    int base));
+# endif
 _GL_CXXALIASWARN (strtoll);
 #elif defined GNULIB_POSIXCHECK
 # undef strtoll
index 7f084f1ba6f53f8cfd30aa54b5efe2b1cba7a59f..5fdb0a7063787beff8e80c36942016dbbbaaef56 100644 (file)
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 58
+# stdlib_h.m4 serial 59
 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,
@@ -170,6 +170,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   REPLACE_STRTOD=0;          AC_SUBST([REPLACE_STRTOD])
   REPLACE_STRTOL=0;          AC_SUBST([REPLACE_STRTOL])
   REPLACE_STRTOLD=0;         AC_SUBST([REPLACE_STRTOLD])
+  REPLACE_STRTOLL=0;         AC_SUBST([REPLACE_STRTOLL])
   REPLACE_STRTOUL=0;         AC_SUBST([REPLACE_STRTOUL])
   REPLACE_STRTOULL=0;        AC_SUBST([REPLACE_STRTOULL])
   REPLACE_UNSETENV=0;        AC_SUBST([REPLACE_UNSETENV])
index d2c9e5310d1c983e7fcc10211cf79fc010a726ea..14455dc3db990dac69edec4a95662656294c7688 100644 (file)
@@ -1,4 +1,4 @@
-# strtoll.m4 serial 8
+# strtoll.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_STRTOLL],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
   AC_CHECK_FUNCS([strtoll])
-  if test $ac_cv_func_strtoll = no; then
+  if test $ac_cv_func_strtoll = yes; then
+    AC_CACHE_CHECK([whether strtoll works],
+      [gl_cv_func_strtoll_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) strtoll (input, &term, 16);
+                if (term != input + 1)
+                  result |= 1;
+              }
+              return result;
+            ]])
+         ],
+         [gl_cv_func_strtoll_works=yes],
+         [gl_cv_func_strtoll_works=no],
+         [case "$host_os" in
+                    # Guess no on native Windows.
+            mingw*) gl_cv_func_strtoll_works="guessing no" ;;
+            *)      gl_cv_func_strtoll_works="$gl_cross_guess_normal" ;;
+          esac
+         ])
+    ])
+    case "$gl_cv_func_strtoll_works" in
+      *yes) ;;
+      *)    REPLACE_STRTOLL=1 ;;
+    esac
+  else
     HAVE_STRTOLL=0
   fi
 ])
index 33b8d500cc8c4756a5d0e481f745a78b9948a25e..ad04ede8196d5fc27fd2e1c08ecf7f7de202ff74 100644 (file)
@@ -142,6 +142,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
              -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
              -e 's|@''REPLACE_STRTOL''@|$(REPLACE_STRTOL)|g' \
              -e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \
+             -e 's|@''REPLACE_STRTOLL''@|$(REPLACE_STRTOLL)|g' \
              -e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \
              -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \
              -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
index 7b6d80c55dae17a12712147b76e7e5b1f30d36fe..da5a5a157a8aeb88be9eab96f122d57dc69c85db 100644 (file)
@@ -12,7 +12,7 @@ stdlib
 
 configure.ac:
 gl_FUNC_STRTOLL
-if test $HAVE_STRTOLL = 0; then
+if test $HAVE_STRTOLL = 0 || test $REPLACE_STRTOLL = 1; then
   AC_LIBOBJ([strtoll])
   gl_PREREQ_STRTOLL
 fi
index ad43fc6f564fc36f7f5a3b71cf5c6f6b4cfe918c..5f2b19331f3561c0bdf5cab29c19d20fdc93687e 100644 (file)
@@ -177,5 +177,67 @@ main (void)
       ASSERT (errno == 0);
     }
 
+  /* Hexadecimal integer syntax.  */
+  {
+    const char input[] = "0x2A";
+    char *ptr;
+    long long result;
+    errno = 0;
+    result = strtoll (input, &ptr, 10);
+    ASSERT (result == 0LL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x2A";
+    char *ptr;
+    long long result;
+    errno = 0;
+    result = strtoll (input, &ptr, 16);
+    ASSERT (result == 42LL);
+    ASSERT (ptr == input + 4);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x2A";
+    char *ptr;
+    long long result;
+    errno = 0;
+    result = strtoll (input, &ptr, 0);
+    ASSERT (result == 42LL);
+    ASSERT (ptr == input + 4);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x";
+    char *ptr;
+    long long result;
+    errno = 0;
+    result = strtoll (input, &ptr, 10);
+    ASSERT (result == 0LL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x";
+    char *ptr;
+    long long result;
+    errno = 0;
+    result = strtoll (input, &ptr, 16);
+    ASSERT (result == 0LL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+  {
+    const char input[] = "0x";
+    char *ptr;
+    long long result;
+    errno = 0;
+    result = strtoll (input, &ptr, 0);
+    ASSERT (result == 0LL);
+    ASSERT (ptr == input + 1);
+    ASSERT (errno == 0);
+  }
+
   return 0;
 }