* lib/stdlib.in.h (strtol): New declaration.
* m4/stdlib_h.m4 (gl_STDLIB_H): Test whether strtol is declared.
(gl_STDLIB_H_DEFAULTS): Initialize GNULIB_STRTOL, HAVE_STRTOL,
REPLACE_STRTOL.
* m4/strtol.m4 (gl_FUNC_STRTOL): Require gl_STDLIB_H_DEFAULTS. Test
whether strtol works. Set REPLACE_STRTOL.
* modules/stdlib (Makefile.am): Substitute GNULIB_STRTOL, HAVE_STRTOL,
REPLACE_STRTOL.
* modules/strtol (Status, Notice): Remove.
(Depends-on): Add stdlib.
(configure.ac): Test HAVE_STRTOL and REPLACE_STRTOL. Invoke
gl_STDLIB_MODULE_INDICATOR.
* tests/test-strtol.c (main): Add tests of hexadecimal integer syntax.
* doc/posix-functions/strtol.texi: Mention the bug.
+2021-04-02 Bruno Haible <bruno@clisp.org>
+
+ strtol: Work around a bug on native Windows and Minix.
+ * lib/stdlib.in.h (strtol): New declaration.
+ * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether strtol is declared.
+ (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_STRTOL, HAVE_STRTOL,
+ REPLACE_STRTOL.
+ * m4/strtol.m4 (gl_FUNC_STRTOL): Require gl_STDLIB_H_DEFAULTS. Test
+ whether strtol works. Set REPLACE_STRTOL.
+ * modules/stdlib (Makefile.am): Substitute GNULIB_STRTOL, HAVE_STRTOL,
+ REPLACE_STRTOL.
+ * modules/strtol (Status, Notice): Remove.
+ (Depends-on): Add stdlib.
+ (configure.ac): Test HAVE_STRTOL and REPLACE_STRTOL. Invoke
+ gl_STDLIB_MODULE_INDICATOR.
+ * tests/test-strtol.c (main): Add tests of hexadecimal integer syntax.
+ * doc/posix-functions/strtol.texi: Mention the bug.
+
2021-04-02 Bruno Haible <bruno@clisp.org>
strtoull: Work around a bug on native Windows and Minix.
@item
This function is missing on some old platforms.
@end itemize
+@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.
Portability problems not fixed by Gnulib:
@itemize
# endif
#endif
+#if @GNULIB_STRTOL@
+/* Parse a signed integer whose textual representation starts at STRING.
+ The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+ it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+ "0x").
+ If ENDPTR is not NULL, the address of the first byte after the integer is
+ stored in *ENDPTR.
+ Upon overflow, the return value is LONG_MAX or LONG_MIN, and errno is set
+ to ERANGE. */
+# if @REPLACE_STRTOL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtol rpl_strtol
+# endif
+# define GNULIB_defined_strtol_function 1
+_GL_FUNCDECL_RPL (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# else
+# if !@HAVE_STRTOL@
+_GL_FUNCDECL_SYS (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtol, long,
+ (const char *restrict string, char **restrict endptr,
+ int base));
+# endif
+_GL_CXXALIASWARN (strtol);
+#elif defined GNULIB_POSIXCHECK
+# undef strtol
+# if HAVE_RAW_DECL_STRTOL
+_GL_WARN_ON_USE (strtol, "strtol is unportable - "
+ "use gnulib module strtol for portability");
+# endif
+#endif
+
#if @GNULIB_STRTOLL@
/* Parse a signed integer whose textual representation starts at STRING.
The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
-# stdlib_h.m4 serial 57
+# stdlib_h.m4 serial 58
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,
posix_memalign posix_openpt ptsname ptsname_r qsort_r
random random_r reallocarray realpath rpmatch secure_getenv setenv
setstate setstate_r srandom srandom_r
- strtod strtold strtoll strtoul strtoull unlockpt unsetenv])
+ strtod strtol strtold strtoll strtoul strtoull unlockpt unsetenv])
AC_REQUIRE([AC_C_RESTRICT])
GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV])
GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV])
GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD])
+ GNULIB_STRTOL=0; AC_SUBST([GNULIB_STRTOL])
GNULIB_STRTOLD=0; AC_SUBST([GNULIB_STRTOLD])
GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL])
GNULIB_STRTOUL=0; AC_SUBST([GNULIB_STRTOUL])
HAVE_SETSTATE=1; AC_SUBST([HAVE_SETSTATE])
HAVE_DECL_SETSTATE=1; AC_SUBST([HAVE_DECL_SETSTATE])
HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD])
+ HAVE_STRTOL=1; AC_SUBST([HAVE_STRTOL])
HAVE_STRTOLD=1; AC_SUBST([HAVE_STRTOLD])
HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL])
HAVE_STRTOUL=1; AC_SUBST([HAVE_STRTOUL])
REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV])
REPLACE_SETSTATE=0; AC_SUBST([REPLACE_SETSTATE])
REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD])
+ REPLACE_STRTOL=0; AC_SUBST([REPLACE_STRTOL])
REPLACE_STRTOLD=0; AC_SUBST([REPLACE_STRTOLD])
REPLACE_STRTOUL=0; AC_SUBST([REPLACE_STRTOUL])
REPLACE_STRTOULL=0; AC_SUBST([REPLACE_STRTOULL])
-# strtol.m4 serial 6
+# strtol.m4 serial 7
dnl Copyright (C) 2002-2003, 2006, 2009-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_STRTOL],
[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
AC_CHECK_FUNCS([strtol])
+ if test $ac_cv_func_strtol = yes; then
+ AC_CACHE_CHECK([whether strtol works],
+ [gl_cv_func_strtol_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) strtol (input, &term, 16);
+ if (term != input + 1)
+ result |= 1;
+ }
+ return result;
+ ]])
+ ],
+ [gl_cv_func_strtol_works=yes],
+ [gl_cv_func_strtol_works=no],
+ [case "$host_os" in
+ # Guess no on native Windows.
+ mingw*) gl_cv_func_strtol_works="guessing no" ;;
+ *) gl_cv_func_strtol_works="$gl_cross_guess_normal" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_strtol_works" in
+ *yes) ;;
+ *) REPLACE_STRTOL=1 ;;
+ esac
+ else
+ HAVE_STRTOL=0
+ fi
])
-e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
-e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \
-e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \
+ -e 's/@''GNULIB_STRTOL''@/$(GNULIB_STRTOL)/g' \
-e 's/@''GNULIB_STRTOLD''@/$(GNULIB_STRTOLD)/g' \
-e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \
-e 's/@''GNULIB_STRTOUL''@/$(GNULIB_STRTOUL)/g' \
-e 's|@''HAVE_SETSTATE''@|$(HAVE_SETSTATE)|g' \
-e 's|@''HAVE_DECL_SETSTATE''@|$(HAVE_DECL_SETSTATE)|g' \
-e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
+ -e 's|@''HAVE_STRTOL''@|$(HAVE_STRTOL)|g' \
-e 's|@''HAVE_STRTOLD''@|$(HAVE_STRTOLD)|g' \
-e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
-e 's|@''HAVE_STRTOUL''@|$(HAVE_STRTOUL)|g' \
-e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
-e 's|@''REPLACE_SETSTATE''@|$(REPLACE_SETSTATE)|g' \
-e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
+ -e 's|@''REPLACE_STRTOL''@|$(REPLACE_STRTOL)|g' \
-e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \
-e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \
-e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \
Description:
strtol() function: convert string to 'long'.
-Status:
-obsolete
-
-Notice:
-This module is obsolete.
-
Files:
lib/strtol.c
m4/strtol.m4
Depends-on:
+stdlib
configure.ac:
gl_FUNC_STRTOL
-if test $ac_cv_func_strtol = no; then
+if test $HAVE_STRTOL = 0 || test $REPLACE_STRTOL = 1; then
AC_LIBOBJ([strtol])
fi
+gl_STDLIB_MODULE_INDICATOR([strtol])
Makefile.am:
ASSERT (errno == 0);
}
+ /* Hexadecimal integer syntax. */
+ {
+ const char input[] = "0x2A";
+ char *ptr;
+ long result;
+ errno = 0;
+ result = strtol (input, &ptr, 10);
+ ASSERT (result == 0L);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x2A";
+ char *ptr;
+ long result;
+ errno = 0;
+ result = strtol (input, &ptr, 16);
+ ASSERT (result == 42L);
+ ASSERT (ptr == input + 4);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x2A";
+ char *ptr;
+ long result;
+ errno = 0;
+ result = strtol (input, &ptr, 0);
+ ASSERT (result == 42L);
+ ASSERT (ptr == input + 4);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x";
+ char *ptr;
+ long result;
+ errno = 0;
+ result = strtol (input, &ptr, 10);
+ ASSERT (result == 0L);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x";
+ char *ptr;
+ long result;
+ errno = 0;
+ result = strtol (input, &ptr, 16);
+ ASSERT (result == 0L);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+ {
+ const char input[] = "0x";
+ char *ptr;
+ long result;
+ errno = 0;
+ result = strtol (input, &ptr, 0);
+ ASSERT (result == 0L);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
+
return 0;
}