* 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>
+
+ 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.
@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:
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
-# 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,
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])
])
-# 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,
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
])
-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)' \
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
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;
}