Hi Eric, > I ran into a mingw bug on strtol() today, and don't see it documented or > worked around in gnulib:
Thanks for the report and test case. The functions strtoul(), strtoll(), strtoull() are equally affected. I'm adding workarounds to gnulib. 2021-04-02 Bruno Haible <br...@clisp.org> strtoul, strtoll, strtoull: Fix compilation warning. * lib/strtol.c (strtol): Undefine before defining as a macro. 2021-04-02 Bruno Haible <br...@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 <br...@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 <br...@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 <br...@clisp.org> strtoul: Work around a bug on native Windows and Minix. Reported by Eric Blake <ebl...@redhat.com> in <https://lists.gnu.org/archive/html/bug-gnulib/2021-03/msg00082.html>. * lib/stdlib.in.h (strtoul): New declaration. * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether strtoul is declared. (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_STRTOUL, HAVE_STRTOUL, REPLACE_STRTOUL. * m4/strtoul.m4 (gl_FUNC_STRTOUL): Require gl_STDLIB_H_DEFAULTS. Test whether strtoul works. Set REPLACE_STRTOUL. * modules/stdlib (Makefile.am): Substitute GNULIB_STRTOUL, HAVE_STRTOUL, REPLACE_STRTOUL. * modules/strtoul (Status, Notice): Remove. (Depends-on): Add stdlib. (configure.ac): Test HAVE_STRTOUL and REPLACE_STRTOUL. Invoke gl_STDLIB_MODULE_INDICATOR. * tests/test-strtoul.c (main): Add tests of hexadecimal integer syntax. * doc/posix-functions/strtoul.texi: Mention the bug. 2021-04-02 Bruno Haible <br...@clisp.org> strtol, strtoul, strtoll, strtoull: Optimize. * lib/strtol.c (GROUP_PARAM_PROTO): New macro. (INTERNAL): Define differently if !USE_NUMBER_GROUPING. (INTERNAL (strtol)): Define without 'int group' parameter if !USE_NUMBER_GROUPING. (strtol): Don't define if !USE_NUMBER_GROUPING. 2021-04-02 Bruno Haible <br...@clisp.org> strto*l: Don't pass invalid arguments to isspace, isalnum, toupper. * lib/strtol.c (ISSPACE, ISALPHA, TOUPPER): Cast argument to 'unsigned char' before passing it to the functions isspace(), isalpha(), toupper().
>From 71958eb7080485d7291b8b622b09e6b198f0d920 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 19:47:53 +0200 Subject: [PATCH 1/7] strto*l: Don't pass invalid arguments to isspace, isalnum, toupper. * lib/strtol.c (ISSPACE, ISALPHA, TOUPPER): Cast argument to 'unsigned char' before passing it to the functions isspace(), isalpha(), toupper(). --- ChangeLog | 7 +++++++ lib/strtol.c | 12 ++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4e766f..0bf4c58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2021-04-02 Bruno Haible <br...@clisp.org> + strto*l: Don't pass invalid arguments to isspace, isalnum, toupper. + * lib/strtol.c (ISSPACE, ISALPHA, TOUPPER): Cast argument to + 'unsigned char' before passing it to the functions isspace(), isalpha(), + toupper(). + +2021-04-02 Bruno Haible <br...@clisp.org> + glob: Reject ~user syntax, when flag GLOB_TILDE_CHECK is given. Reported and patch suggested by Eli Zaretskii <e...@gnu.org> in <https://lists.gnu.org/archive/html/bug-gnulib/2021-03/msg00136.html>. diff --git a/lib/strtol.c b/lib/strtol.c index 2f2159b..14836d0 100644 --- a/lib/strtol.c +++ b/lib/strtol.c @@ -166,13 +166,13 @@ # define UCHAR_TYPE unsigned char # define STRING_TYPE char # ifdef USE_IN_EXTENDED_LOCALE_MODEL -# define ISSPACE(Ch) __isspace_l ((Ch), loc) -# define ISALPHA(Ch) __isalpha_l ((Ch), loc) -# define TOUPPER(Ch) __toupper_l ((Ch), loc) +# define ISSPACE(Ch) __isspace_l ((unsigned char) (Ch), loc) +# define ISALPHA(Ch) __isalpha_l ((unsigned char) (Ch), loc) +# define TOUPPER(Ch) __toupper_l ((unsigned char) (Ch), loc) # else -# define ISSPACE(Ch) isspace (Ch) -# define ISALPHA(Ch) isalpha (Ch) -# define TOUPPER(Ch) toupper (Ch) +# define ISSPACE(Ch) isspace ((unsigned char) (Ch)) +# define ISALPHA(Ch) isalpha ((unsigned char) (Ch)) +# define TOUPPER(Ch) toupper ((unsigned char) (Ch)) # endif #endif -- 2.7.4
>From 022521230ffa940a5428ee2a50120dc882920b16 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 19:50:19 +0200 Subject: [PATCH 2/7] strtol, strtoul, strtoll, strtoull: Optimize. * lib/strtol.c (GROUP_PARAM_PROTO): New macro. (INTERNAL): Define differently if !USE_NUMBER_GROUPING. (INTERNAL (strtol)): Define without 'int group' parameter if !USE_NUMBER_GROUPING. (strtol): Don't define if !USE_NUMBER_GROUPING. --- ChangeLog | 9 +++++++++ lib/strtol.c | 25 ++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bf4c58..d5b833a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2021-04-02 Bruno Haible <br...@clisp.org> + strtol, strtoul, strtoll, strtoull: Optimize. + * lib/strtol.c (GROUP_PARAM_PROTO): New macro. + (INTERNAL): Define differently if !USE_NUMBER_GROUPING. + (INTERNAL (strtol)): Define without 'int group' parameter if + !USE_NUMBER_GROUPING. + (strtol): Don't define if !USE_NUMBER_GROUPING. + +2021-04-02 Bruno Haible <br...@clisp.org> + strto*l: Don't pass invalid arguments to isspace, isalnum, toupper. * lib/strtol.c (ISSPACE, ISALPHA, TOUPPER): Cast argument to 'unsigned char' before passing it to the functions isspace(), isalpha(), diff --git a/lib/strtol.c b/lib/strtol.c index 14836d0..c30e5b4 100644 --- a/lib/strtol.c +++ b/lib/strtol.c @@ -131,6 +131,12 @@ #endif +#ifdef USE_NUMBER_GROUPING +# define GROUP_PARAM_PROTO , int group +#else +# define GROUP_PARAM_PROTO +#endif + /* We use this code also for the extended locale handling where the function gets as an additional argument the locale which has to be used. To access the values we have to redefine the _NL_CURRENT @@ -176,9 +182,13 @@ # endif #endif -#define INTERNAL(X) INTERNAL1(X) -#define INTERNAL1(X) __##X##_internal -#define WEAKNAME(X) WEAKNAME1(X) +#ifdef USE_NUMBER_GROUPING +# define INTERNAL(X) INTERNAL1(X) +# define INTERNAL1(X) __##X##_internal +# define WEAKNAME(X) WEAKNAME1(X) +#else +# define INTERNAL(X) X +#endif #ifdef USE_NUMBER_GROUPING /* This file defines a function to check for correct grouping. */ @@ -196,7 +206,7 @@ INT INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, - int base, int group LOCALE_PARAM_PROTO) + int base GROUP_PARAM_PROTO LOCALE_PARAM_PROTO) { int negative; register unsigned LONG int cutoff; @@ -379,15 +389,16 @@ noconv: return 0L; } +#ifdef USE_NUMBER_GROUPING /* External user entry point. */ - INT -#ifdef weak_function +# ifdef weak_function weak_function -#endif +# endif strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr, int base LOCALE_PARAM_PROTO) { return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM); } +#endif -- 2.7.4
>From cbff21f910e678340da2cadf0bbf2bdc191c0eb9 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 19:56:28 +0200 Subject: [PATCH 3/7] strtoul: Work around a bug on native Windows and Minix. Reported by Eric Blake <ebl...@redhat.com> in <https://lists.gnu.org/archive/html/bug-gnulib/2021-03/msg00082.html>. * lib/stdlib.in.h (strtoul): New declaration. * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether strtoul is declared. (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_STRTOUL, HAVE_STRTOUL, REPLACE_STRTOUL. * m4/strtoul.m4 (gl_FUNC_STRTOUL): Require gl_STDLIB_H_DEFAULTS. Test whether strtoul works. Set REPLACE_STRTOUL. * modules/stdlib (Makefile.am): Substitute GNULIB_STRTOUL, HAVE_STRTOUL, REPLACE_STRTOUL. * modules/strtoul (Status, Notice): Remove. (Depends-on): Add stdlib. (configure.ac): Test HAVE_STRTOUL and REPLACE_STRTOUL. Invoke gl_STDLIB_MODULE_INDICATOR. * tests/test-strtoul.c (main): Add tests of hexadecimal integer syntax. * doc/posix-functions/strtoul.texi: Mention the bug. --- ChangeLog | 20 +++++++++++++ doc/posix-functions/strtoul.texi | 4 +++ lib/stdlib.in.h | 40 ++++++++++++++++++++++++++ m4/stdlib_h.m4 | 7 +++-- m4/strtoul.m4 | 38 +++++++++++++++++++++++- modules/stdlib | 3 ++ modules/strtoul | 10 ++----- tests/test-strtoul.c | 62 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 174 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5b833a..9ce3bae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2021-04-02 Bruno Haible <br...@clisp.org> + strtoul: Work around a bug on native Windows and Minix. + Reported by Eric Blake <ebl...@redhat.com> in + <https://lists.gnu.org/archive/html/bug-gnulib/2021-03/msg00082.html>. + * lib/stdlib.in.h (strtoul): New declaration. + * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether strtoul is declared. + (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_STRTOUL, HAVE_STRTOUL, + REPLACE_STRTOUL. + * m4/strtoul.m4 (gl_FUNC_STRTOUL): Require gl_STDLIB_H_DEFAULTS. Test + whether strtoul works. Set REPLACE_STRTOUL. + * modules/stdlib (Makefile.am): Substitute GNULIB_STRTOUL, HAVE_STRTOUL, + REPLACE_STRTOUL. + * modules/strtoul (Status, Notice): Remove. + (Depends-on): Add stdlib. + (configure.ac): Test HAVE_STRTOUL and REPLACE_STRTOUL. Invoke + gl_STDLIB_MODULE_INDICATOR. + * tests/test-strtoul.c (main): Add tests of hexadecimal integer syntax. + * doc/posix-functions/strtoul.texi: Mention the bug. + +2021-04-02 Bruno Haible <br...@clisp.org> + strtol, strtoul, strtoll, strtoull: Optimize. * lib/strtol.c (GROUP_PARAM_PROTO): New macro. (INTERNAL): Define differently if !USE_NUMBER_GROUPING. diff --git a/doc/posix-functions/strtoul.texi b/doc/posix-functions/strtoul.texi index b79b56b..3b1fa7f 100644 --- a/doc/posix-functions/strtoul.texi +++ b/doc/posix-functions/strtoul.texi @@ -10,6 +10,10 @@ Portability problems fixed by Gnulib: @itemize @item This function is missing on some old platforms. +@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: diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 49fc44e..0a377c0 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -1229,6 +1229,46 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - " # endif #endif +#if @GNULIB_STRTOUL@ +/* Parse an unsigned 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 ULONG_MAX, and errno is set to ERANGE. */ +# if @REPLACE_STRTOUL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtoul rpl_strtoul +# endif +# define GNULIB_defined_strtoul_function 1 +_GL_FUNCDECL_RPL (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base)); +# else +# if !@HAVE_STRTOUL@ +_GL_FUNCDECL_SYS (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base)); +# endif +_GL_CXXALIASWARN (strtoul); +#elif defined GNULIB_POSIXCHECK +# undef strtoul +# if HAVE_RAW_DECL_STRTOUL +_GL_WARN_ON_USE (strtoul, "strtoul is unportable - " + "use gnulib module strtoul for portability"); +# endif +#endif + #if @GNULIB_STRTOULL@ /* Parse an unsigned integer whose textual representation starts at STRING. The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 5a02972..5895586 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 55 +# stdlib_h.m4 serial 56 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, @@ -28,7 +28,7 @@ AC_DEFUN([gl_STDLIB_H], 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 strtoull unlockpt unsetenv]) + strtod strtold strtoll strtoul strtoull unlockpt unsetenv]) AC_REQUIRE([AC_C_RESTRICT]) @@ -90,6 +90,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD]) GNULIB_STRTOLD=0; AC_SUBST([GNULIB_STRTOLD]) GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL]) + GNULIB_STRTOUL=0; AC_SUBST([GNULIB_STRTOUL]) GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL]) GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX]) GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) @@ -139,6 +140,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD]) HAVE_STRTOLD=1; AC_SUBST([HAVE_STRTOLD]) HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL]) + HAVE_STRTOUL=1; AC_SUBST([HAVE_STRTOUL]) HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL]) HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) @@ -165,6 +167,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], REPLACE_SETSTATE=0; AC_SUBST([REPLACE_SETSTATE]) REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD]) REPLACE_STRTOLD=0; AC_SUBST([REPLACE_STRTOLD]) + REPLACE_STRTOUL=0; AC_SUBST([REPLACE_STRTOUL]) REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) ]) diff --git a/m4/strtoul.m4 b/m4/strtoul.m4 index 853c1a6..b915679 100644 --- a/m4/strtoul.m4 +++ b/m4/strtoul.m4 @@ -1,4 +1,4 @@ -# strtoul.m4 serial 5 +# strtoul.m4 serial 6 dnl Copyright (C) 2002, 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, @@ -6,5 +6,41 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_STRTOUL], [ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) AC_CHECK_FUNCS([strtoul]) + if test $ac_cv_func_strtoul = yes; then + AC_CACHE_CHECK([whether strtoul works], + [gl_cv_func_strtoul_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) strtoul (input, &term, 16); + if (term != input + 1) + result |= 1; + } + return result; + ]]) + ], + [gl_cv_func_strtoul_works=yes], + [gl_cv_func_strtoul_works=no], + [case "$host_os" in + # Guess no on native Windows. + mingw*) gl_cv_func_strtoul_works="guessing no" ;; + *) gl_cv_func_strtoul_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_strtoul_works" in + *yes) ;; + *) REPLACE_STRTOUL=1 ;; + esac + else + HAVE_STRTOUL=0 + fi ]) diff --git a/modules/stdlib b/modules/stdlib index 9b65a01..998f44d 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -64,6 +64,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ -e 's/@''GNULIB_STRTOLD''@/$(GNULIB_STRTOLD)/g' \ -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ + -e 's/@''GNULIB_STRTOUL''@/$(GNULIB_STRTOUL)/g' \ -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ @@ -111,6 +112,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ -e 's|@''HAVE_STRTOLD''@|$(HAVE_STRTOLD)|g' \ -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOUL''@|$(HAVE_STRTOUL)|g' \ -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ @@ -137,6 +139,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''REPLACE_SETSTATE''@|$(REPLACE_SETSTATE)|g' \ -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ -e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \ + -e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \ -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ diff --git a/modules/strtoul b/modules/strtoul index 7f3139c..c790e41 100644 --- a/modules/strtoul +++ b/modules/strtoul @@ -1,24 +1,20 @@ Description: strtoul() function: convert string to 'unsigned long'. -Status: -obsolete - -Notice: -This module is obsolete. - Files: lib/strtol.c lib/strtoul.c m4/strtoul.m4 Depends-on: +stdlib configure.ac: gl_FUNC_STRTOUL -if test $ac_cv_func_strtoul = no; then +if test $HAVE_STRTOUL = 0 || test $REPLACE_STRTOUL = 1; then AC_LIBOBJ([strtoul]) fi +gl_STDLIB_MODULE_INDICATOR([strtoul]) Makefile.am: diff --git a/tests/test-strtoul.c b/tests/test-strtoul.c index 0e1917d..d34272b 100644 --- a/tests/test-strtoul.c +++ b/tests/test-strtoul.c @@ -176,5 +176,67 @@ main (void) ASSERT (errno == 0); } + /* Hexadecimal integer syntax. */ + { + const char input[] = "0x2A"; + char *ptr; + unsigned long result; + errno = 0; + result = strtoul (input, &ptr, 10); + ASSERT (result == 0UL); + ASSERT (ptr == input + 1); + ASSERT (errno == 0); + } + { + const char input[] = "0x2A"; + char *ptr; + unsigned long result; + errno = 0; + result = strtoul (input, &ptr, 16); + ASSERT (result == 42UL); + ASSERT (ptr == input + 4); + ASSERT (errno == 0); + } + { + const char input[] = "0x2A"; + char *ptr; + unsigned long result; + errno = 0; + result = strtoul (input, &ptr, 0); + ASSERT (result == 42UL); + ASSERT (ptr == input + 4); + ASSERT (errno == 0); + } + { + const char input[] = "0x"; + char *ptr; + unsigned long result; + errno = 0; + result = strtoul (input, &ptr, 10); + ASSERT (result == 0UL); + ASSERT (ptr == input + 1); + ASSERT (errno == 0); + } + { + const char input[] = "0x"; + char *ptr; + unsigned long result; + errno = 0; + result = strtoul (input, &ptr, 16); + ASSERT (result == 0UL); + ASSERT (ptr == input + 1); + ASSERT (errno == 0); + } + { + const char input[] = "0x"; + char *ptr; + unsigned long result; + errno = 0; + result = strtoul (input, &ptr, 0); + ASSERT (result == 0UL); + ASSERT (ptr == input + 1); + ASSERT (errno == 0); + } + return 0; } -- 2.7.4
>From 837ffb5ee4585ce6947e1013d03c7d6f21cbd635 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 20:14:28 +0200 Subject: [PATCH 4/7] 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. --- ChangeLog | 12 ++++++++ doc/posix-functions/strtoull.texi | 4 +++ lib/stdlib.in.h | 18 ++++++++++-- m4/stdlib_h.m4 | 3 +- m4/strtoull.m4 | 36 +++++++++++++++++++++-- modules/stdlib | 1 + modules/strtoull | 2 +- tests/test-strtoull.c | 62 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 132 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ce3bae..5d752ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2021-04-02 Bruno Haible <br...@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 <br...@clisp.org> + strtoul: Work around a bug on native Windows and Minix. Reported by Eric Blake <ebl...@redhat.com> in <https://lists.gnu.org/archive/html/bug-gnulib/2021-03/msg00082.html>. diff --git a/doc/posix-functions/strtoull.texi b/doc/posix-functions/strtoull.texi index 2057fc7..68ede34 100644 --- a/doc/posix-functions/strtoull.texi +++ b/doc/posix-functions/strtoull.texi @@ -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: diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 0a377c0..0506362 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -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 diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 5895586..652ba86 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -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]) ]) diff --git a/m4/strtoull.m4 b/m4/strtoull.m4 index 88867ee..41178cc 100644 --- a/m4/strtoull.m4 +++ b/m4/strtoull.m4 @@ -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 ]) diff --git a/modules/stdlib b/modules/stdlib index 998f44d..4bd7a5c 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -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)' \ diff --git a/modules/strtoull b/modules/strtoull index ff83b69..9b5895b 100644 --- a/modules/strtoull +++ b/modules/strtoull @@ -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 diff --git a/tests/test-strtoull.c b/tests/test-strtoull.c index 8242d3c..db7b371 100644 --- a/tests/test-strtoull.c +++ b/tests/test-strtoull.c @@ -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; } -- 2.7.4
>From 705c23696fcaf5bd9d4f0aaecd106b4a2c1417b2 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 20:42:13 +0200 Subject: [PATCH 5/7] 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. --- ChangeLog | 18 ++++++++++++ doc/posix-functions/strtol.texi | 4 +++ lib/stdlib.in.h | 41 +++++++++++++++++++++++++++ m4/stdlib_h.m4 | 7 +++-- m4/strtol.m4 | 38 ++++++++++++++++++++++++- modules/stdlib | 3 ++ modules/strtol | 10 ++----- tests/test-strtol.c | 62 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 173 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5d752ab..9a84589 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2021-04-02 Bruno Haible <br...@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 <br...@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. diff --git a/doc/posix-functions/strtol.texi b/doc/posix-functions/strtol.texi index bf539c4..c9333ce 100644 --- a/doc/posix-functions/strtol.texi +++ b/doc/posix-functions/strtol.texi @@ -11,6 +11,10 @@ Portability problems fixed by Gnulib: @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 diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 0506362..e2c461b 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -1202,6 +1202,47 @@ _GL_WARN_ON_USE (strtold, "strtold is unportable - " # 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, diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 652ba86..7f084f1 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# 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, @@ -28,7 +28,7 @@ AC_DEFUN([gl_STDLIB_H], 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]) @@ -88,6 +88,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], 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]) @@ -138,6 +139,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], 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]) @@ -166,6 +168,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], 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]) diff --git a/m4/strtol.m4 b/m4/strtol.m4 index ec7b8d1..343507b 100644 --- a/m4/strtol.m4 +++ b/m4/strtol.m4 @@ -1,4 +1,4 @@ -# 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, @@ -6,5 +6,41 @@ dnl with or without modifications, as long as this notice is preserved. 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 ]) diff --git a/modules/stdlib b/modules/stdlib index 4bd7a5c..33b8d50 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -62,6 +62,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -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' \ @@ -110,6 +111,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -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' \ @@ -138,6 +140,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -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' \ diff --git a/modules/strtol b/modules/strtol index 65b6946..24d4c73 100644 --- a/modules/strtol +++ b/modules/strtol @@ -1,23 +1,19 @@ 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: diff --git a/tests/test-strtol.c b/tests/test-strtol.c index 105bc58..467514c 100644 --- a/tests/test-strtol.c +++ b/tests/test-strtol.c @@ -177,5 +177,67 @@ main (void) 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; } -- 2.7.4
>From ea1816fd6d334b4bfd8368a63d9bda3cad1c9b0d Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 20:46:15 +0200 Subject: [PATCH 6/7] 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. --- ChangeLog | 12 ++++++++ doc/posix-functions/strtoll.texi | 4 +++ lib/stdlib.in.h | 18 ++++++++++-- m4/stdlib_h.m4 | 3 +- m4/strtoll.m4 | 36 +++++++++++++++++++++-- modules/stdlib | 1 + modules/strtoll | 2 +- tests/test-strtoll.c | 62 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 132 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a84589..b479574 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2021-04-02 Bruno Haible <br...@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 <br...@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. diff --git a/doc/posix-functions/strtoll.texi b/doc/posix-functions/strtoll.texi index 45a7035..b507fc3 100644 --- a/doc/posix-functions/strtoll.texi +++ b/doc/posix-functions/strtoll.texi @@ -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: diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index e2c461b..c07fd1f 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -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 diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 7f084f1..5fdb0a7 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -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]) diff --git a/m4/strtoll.m4 b/m4/strtoll.m4 index d2c9e53..14455dc 100644 --- a/m4/strtoll.m4 +++ b/m4/strtoll.m4 @@ -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 ]) diff --git a/modules/stdlib b/modules/stdlib index 33b8d50..ad04ede 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -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' \ diff --git a/modules/strtoll b/modules/strtoll index 7b6d80c..da5a5a1 100644 --- a/modules/strtoll +++ b/modules/strtoll @@ -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 diff --git a/tests/test-strtoll.c b/tests/test-strtoll.c index ad43fc6..5f2b193 100644 --- a/tests/test-strtoll.c +++ b/tests/test-strtoll.c @@ -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; } -- 2.7.4
>From 2b038f1cc7e9a7e0a6257527a127a87753fc794c Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 2 Apr 2021 20:56:28 +0200 Subject: [PATCH 7/7] strtoul, strtoll, strtoull: Fix compilation warning. * lib/strtol.c (strtol): Undefine before defining as a macro. --- ChangeLog | 5 +++++ lib/strtol.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index b479574..6224aa7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2021-04-02 Bruno Haible <br...@clisp.org> + strtoul, strtoll, strtoull: Fix compilation warning. + * lib/strtol.c (strtol): Undefine before defining as a macro. + +2021-04-02 Bruno Haible <br...@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. diff --git a/lib/strtol.c b/lib/strtol.c index c30e5b4..c904482 100644 --- a/lib/strtol.c +++ b/lib/strtol.c @@ -51,6 +51,7 @@ /* Determine the name. */ #ifdef USE_IN_EXTENDED_LOCALE_MODEL +# undef strtol # if UNSIGNED # ifdef USE_WIDE_CHAR # ifdef QUAD @@ -82,6 +83,7 @@ # endif #else # if UNSIGNED +# undef strtol # ifdef USE_WIDE_CHAR # ifdef QUAD # define strtol wcstoull @@ -97,6 +99,7 @@ # endif # else # ifdef USE_WIDE_CHAR +# undef strtol # ifdef QUAD # define strtol wcstoll # else @@ -104,6 +107,7 @@ # endif # else # ifdef QUAD +# undef strtol # define strtol strtoll # endif # endif -- 2.7.4