This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Import strchrnul from gnulib and use it
- From: Sergio Durigan Junior <sergiodj at redhat dot com>
- To: Simon Marchi <simon dot marchi at ericsson dot com>
- Cc: <gdb-patches at sourceware dot org>
- Date: Wed, 27 Jan 2016 16:43:45 -0500
- Subject: Re: [PATCH] Import strchrnul from gnulib and use it
- Authentication-results: sourceware.org; auth=none
- References: <1453928650-30750-1-git-send-email-simon dot marchi at ericsson dot com>
On Wednesday, January 27 2016, Simon Marchi wrote:
> For a forthcoming patch, I need a "skip_to_colon" function. I noticed
> there are two skip_to_semicolon (one in gdb and one in gdbserver). I
> thought we could put it in common/, and generalize it for any character.
> It turns out that the strchrnul function does exactly that. I imported
> the corresponding module from gnulib, for those systems that do not have
> it.
>
> There are probably more places where this function can be used instead
> of doing the work by hand (I am looking at
> remote-utils.c::look_up_one_symbol).
Thanks for doing this, Simon.
LGTM.
> gdb/ChangeLog:
>
> * remote.c (skip_to_semicolon): Remove.
> (remote_parse_stop_reply): Use strchrnul instead of
> skip_to_semicolon.
> * gnulib/update-gnulib.sh (IMPORTED_GNULIB_MODULES): Add
> strchrnul.
> * gnulib/aclocal.m4: Regenerate.
> * gnulib/config.in: Regenerate.
> * gnulib/configure: Regenerate.
> * gnulib/import/Makefile.am: Regenerate.
> * gnulib/import/Makefile.in: Regenerate.
> * gnulib/import/m4/gnulib-cache.m4: Regenerate.
> * gnulib/import/m4/gnulib-comp.m4: Regenerate.
> * gnulib/import/m4/rawmemchr.m4: New file.
> * gnulib/import/m4/strchrnul.m4: New file.
> * gnulib/import/rawmemchr.c: New file.
> * gnulib/import/rawmemchr.valgrind: New file.
> * gnulib/import/strchrnul.c: New file.
> * gnulib/import/strchrnul.valgrind: New file.
>
> gdb/gdbserver/ChangeLog:
>
> * server.c (skip_to_semicolon): Remove.
> (process_point_options): Use strchrnul instead of
> skip_to_semicolon.
> ---
> gdb/gdbserver/server.c | 15 +---
> gdb/gnulib/aclocal.m4 | 2 +
> gdb/gnulib/config.in | 12 +++
> gdb/gnulib/configure | 158 +++++++++++++++++++++++++++++++++++
> gdb/gnulib/import/Makefile.am | 20 ++++-
> gdb/gnulib/import/Makefile.in | 25 +++---
> gdb/gnulib/import/m4/gnulib-cache.m4 | 3 +-
> gdb/gnulib/import/m4/gnulib-comp.m4 | 20 +++++
> gdb/gnulib/import/m4/rawmemchr.m4 | 20 +++++
> gdb/gnulib/import/m4/strchrnul.m4 | 50 +++++++++++
> gdb/gnulib/import/rawmemchr.c | 136 ++++++++++++++++++++++++++++++
> gdb/gnulib/import/rawmemchr.valgrind | 12 +++
> gdb/gnulib/import/strchrnul.c | 142 +++++++++++++++++++++++++++++++
> gdb/gnulib/import/strchrnul.valgrind | 12 +++
> gdb/gnulib/update-gnulib.sh | 1 +
> gdb/remote.c | 26 ++----
> 16 files changed, 612 insertions(+), 42 deletions(-)
> create mode 100644 gdb/gnulib/import/m4/rawmemchr.m4
> create mode 100644 gdb/gnulib/import/m4/strchrnul.m4
> create mode 100644 gdb/gnulib/import/rawmemchr.c
> create mode 100644 gdb/gnulib/import/rawmemchr.valgrind
> create mode 100644 gdb/gnulib/import/strchrnul.c
> create mode 100644 gdb/gnulib/import/strchrnul.valgrind
>
> diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
> index 301dea9..ef715e7 100644
> --- a/gdb/gdbserver/server.c
> +++ b/gdb/gdbserver/server.c
> @@ -3820,15 +3820,6 @@ main (int argc, char *argv[])
> gdb_assert_not_reached ("captured_main should never return");
> }
>
> -/* Skip PACKET until the next semi-colon (or end of string). */
> -
> -static void
> -skip_to_semicolon (char **packet)
> -{
> - while (**packet != '\0' && **packet != ';')
> - (*packet)++;
> -}
> -
> /* Process options coming from Z packets for a breakpoint. PACKET is
> the packet buffer. *PACKET is updated to point to the first char
> after the last processed option. */
> @@ -3856,7 +3847,7 @@ process_point_options (struct breakpoint *bp, char **packet)
> if (debug_threads)
> debug_printf ("Found breakpoint condition.\n");
> if (!add_breakpoint_condition (bp, &dataptr))
> - skip_to_semicolon (&dataptr);
> + dataptr = strchrnul (dataptr, ';');
> }
> else if (startswith (dataptr, "cmds:"))
> {
> @@ -3866,14 +3857,14 @@ process_point_options (struct breakpoint *bp, char **packet)
> persist = (*dataptr == '1');
> dataptr += 2;
> if (add_breakpoint_commands (bp, &dataptr, persist))
> - skip_to_semicolon (&dataptr);
> + dataptr = strchrnul (dataptr, ';');
> }
> else
> {
> fprintf (stderr, "Unknown token %c, ignoring.\n",
> *dataptr);
> /* Skip tokens until we find one that we recognize. */
> - skip_to_semicolon (&dataptr);
> + dataptr = strchrnul (dataptr, ';');
> }
> }
> *packet = dataptr;
> diff --git a/gdb/gnulib/aclocal.m4 b/gdb/gnulib/aclocal.m4
> index 5977e47..e5cc409 100644
> --- a/gdb/gnulib/aclocal.m4
> +++ b/gdb/gnulib/aclocal.m4
> @@ -1064,6 +1064,7 @@ m4_include([import/m4/multiarch.m4])
> m4_include([import/m4/nocrash.m4])
> m4_include([import/m4/off_t.m4])
> m4_include([import/m4/pathmax.m4])
> +m4_include([import/m4/rawmemchr.m4])
> m4_include([import/m4/readlink.m4])
> m4_include([import/m4/rename.m4])
> m4_include([import/m4/rmdir.m4])
> @@ -1075,6 +1076,7 @@ m4_include([import/m4/stddef_h.m4])
> m4_include([import/m4/stdint.m4])
> m4_include([import/m4/stdio_h.m4])
> m4_include([import/m4/stdlib_h.m4])
> +m4_include([import/m4/strchrnul.m4])
> m4_include([import/m4/string_h.m4])
> m4_include([import/m4/strstr.m4])
> m4_include([import/m4/strtok_r.m4])
> diff --git a/gdb/gnulib/config.in b/gdb/gnulib/config.in
> index 4587003..1371394 100644
> --- a/gdb/gnulib/config.in
> +++ b/gdb/gnulib/config.in
> @@ -113,6 +113,9 @@
> /* Define to 1 when the gnulib module memmem should be tested. */
> #undef GNULIB_TEST_MEMMEM
>
> +/* Define to 1 when the gnulib module rawmemchr should be tested. */
> +#undef GNULIB_TEST_RAWMEMCHR
> +
> /* Define to 1 when the gnulib module readlink should be tested. */
> #undef GNULIB_TEST_READLINK
>
> @@ -128,6 +131,9 @@
> /* Define to 1 when the gnulib module stat should be tested. */
> #undef GNULIB_TEST_STAT
>
> +/* Define to 1 when the gnulib module strchrnul should be tested. */
> +#undef GNULIB_TEST_STRCHRNUL
> +
> /* Define to 1 when the gnulib module strstr should be tested. */
> #undef GNULIB_TEST_STRSTR
>
> @@ -276,6 +282,9 @@
> /* Define to 1 if you have the `mprotect' function. */
> #undef HAVE_MPROTECT
>
> +/* Define to 1 if you have the `rawmemchr' function. */
> +#undef HAVE_RAWMEMCHR
> +
> /* Define to 1 if acosf is declared even after undefining macros. */
> #undef HAVE_RAW_DECL_ACOSF
>
> @@ -1117,6 +1126,9 @@
> /* Define to 1 if you have the <stdlib.h> header file. */
> #undef HAVE_STDLIB_H
>
> +/* Define to 1 if you have the `strchrnul' function. */
> +#undef HAVE_STRCHRNUL
> +
> /* Define to 1 if you have the <strings.h> header file. */
> #undef HAVE_STRINGS_H
>
> diff --git a/gdb/gnulib/configure b/gdb/gnulib/configure
> index 23ff364..540bad3 100644
> --- a/gdb/gnulib/configure
> +++ b/gdb/gnulib/configure
> @@ -5320,6 +5320,7 @@ fi
> # Code from module multiarch:
> # Code from module nocrash:
> # Code from module pathmax:
> + # Code from module rawmemchr:
> # Code from module readlink:
> # Code from module rename:
> # Code from module rmdir:
> @@ -5336,6 +5337,7 @@ fi
> # Code from module stdint:
> # Code from module stdio:
> # Code from module stdlib:
> + # Code from module strchrnul:
> # Code from module streq:
> # Code from module string:
> # Code from module strnlen1:
> @@ -16121,6 +16123,53 @@ $as_echo "#define GNULIB_TEST_MEMMEM 1" >>confdefs.h
>
>
>
> +
> + for ac_func in rawmemchr
> +do :
> + ac_fn_c_check_func "$LINENO" "rawmemchr" "ac_cv_func_rawmemchr"
> +if test "x$ac_cv_func_rawmemchr" = x""yes; then :
> + cat >>confdefs.h <<_ACEOF
> +#define HAVE_RAWMEMCHR 1
> +_ACEOF
> +
> +fi
> +done
> +
> + if test $ac_cv_func_rawmemchr = no; then
> + HAVE_RAWMEMCHR=0
> + fi
> +
> + if test $HAVE_RAWMEMCHR = 0; then
> +
> +
> +
> +
> +
> +
> +
> +
> + gl_LIBOBJS="$gl_LIBOBJS rawmemchr.$ac_objext"
> +
> + :
> + fi
> +
> +
> +
> +
> +
> + GNULIB_RAWMEMCHR=1
> +
> +
> +
> +
> +
> +$as_echo "#define GNULIB_TEST_RAWMEMCHR 1" >>confdefs.h
> +
> +
> +
> +
> +
> +
> if test $ac_cv_func_readlink = no; then
> HAVE_READLINK=0
> else
> @@ -17428,6 +17477,115 @@ fi
>
>
>
> + for ac_func in strchrnul
> +do :
> + ac_fn_c_check_func "$LINENO" "strchrnul" "ac_cv_func_strchrnul"
> +if test "x$ac_cv_func_strchrnul" = x""yes; then :
> + cat >>confdefs.h <<_ACEOF
> +#define HAVE_STRCHRNUL 1
> +_ACEOF
> +
> +fi
> +done
> +
> + if test $ac_cv_func_strchrnul = no; then
> + HAVE_STRCHRNUL=0
> + else
> + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strchrnul works" >&5
> +$as_echo_n "checking whether strchrnul works... " >&6; }
> +if test "${gl_cv_func_strchrnul_works+set}" = set; then :
> + $as_echo_n "(cached) " >&6
> +else
> + if test "$cross_compiling" = yes; then :
> + cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h. */
> +
> +#if defined __CYGWIN__
> + #include <cygwin/version.h>
> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 9)
> + Lucky user
> + #endif
> +#else
> + Lucky user
> +#endif
> +
> +_ACEOF
> +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
> + $EGREP "Lucky user" >/dev/null 2>&1; then :
> + gl_cv_func_strchrnul_works="guessing yes"
> +else
> + gl_cv_func_strchrnul_works="guessing no"
> +fi
> +rm -f conftest*
> +
> +
> +else
> + cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h. */
> +
> +#include <string.h> /* for strchrnul */
> +
> +int
> +main ()
> +{
> +const char *buf = "a";
> + return strchrnul (buf, 'b') != buf + 1;
> +
> + ;
> + return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_run "$LINENO"; then :
> + gl_cv_func_strchrnul_works=yes
> +else
> + gl_cv_func_strchrnul_works=no
> +fi
> +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
> + conftest.$ac_objext conftest.beam conftest.$ac_ext
> +fi
> +
> +
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_strchrnul_works" >&5
> +$as_echo "$gl_cv_func_strchrnul_works" >&6; }
> + case "$gl_cv_func_strchrnul_works" in
> + *yes) ;;
> + *) REPLACE_STRCHRNUL=1 ;;
> + esac
> + fi
> +
> + if test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1; then
> +
> +
> +
> +
> +
> +
> +
> +
> + gl_LIBOBJS="$gl_LIBOBJS strchrnul.$ac_objext"
> +
> + :
> + fi
> +
> +
> +
> +
> +
> + GNULIB_STRCHRNUL=1
> +
> +
> +
> +
> +
> +$as_echo "#define GNULIB_TEST_STRCHRNUL 1" >>confdefs.h
> +
> +
> +
> +
> +
> +
> +
>
> if test $REPLACE_STRSTR = 0; then
> { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strstr works in linear time" >&5
> diff --git a/gdb/gnulib/import/Makefile.am b/gdb/gnulib/import/Makefile.am
> index 32dab67..3fb324b 100644
> --- a/gdb/gnulib/import/Makefile.am
> +++ b/gdb/gnulib/import/Makefile.am
> @@ -21,7 +21,7 @@
> # the same distribution terms as the rest of that program.
> #
> # Generated by gnulib-tool.
> -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes lstat memchr memmem pathmax readlink rename signal-h strstr strtok_r sys_stat unistd update-copyright wchar wctype-h
> +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes lstat memchr memmem pathmax readlink rename signal-h strchrnul strstr strtok_r sys_stat unistd update-copyright wchar wctype-h
>
> AUTOMAKE_OPTIONS = 1.9.6 gnits
>
> @@ -842,6 +842,15 @@ EXTRA_DIST += pathmax.h
>
> ## end gnulib module pathmax
>
> +## begin gnulib module rawmemchr
> +
> +
> +EXTRA_DIST += rawmemchr.c rawmemchr.valgrind
> +
> +EXTRA_libgnu_a_SOURCES += rawmemchr.c
> +
> +## end gnulib module rawmemchr
> +
> ## begin gnulib module readlink
>
>
> @@ -1345,6 +1354,15 @@ EXTRA_DIST += stdlib.in.h
>
> ## end gnulib module stdlib
>
> +## begin gnulib module strchrnul
> +
> +
> +EXTRA_DIST += strchrnul.c strchrnul.valgrind
> +
> +EXTRA_libgnu_a_SOURCES += strchrnul.c
> +
> +## end gnulib module strchrnul
> +
> ## begin gnulib module streq
>
>
> diff --git a/gdb/gnulib/import/Makefile.in b/gdb/gnulib/import/Makefile.in
> index f2324d0..d771e15 100644
> --- a/gdb/gnulib/import/Makefile.in
> +++ b/gdb/gnulib/import/Makefile.in
> @@ -36,7 +36,7 @@
> # the same distribution terms as the rest of that program.
> #
> # Generated by gnulib-tool.
> -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes lstat memchr memmem pathmax readlink rename signal-h strstr strtok_r sys_stat unistd update-copyright wchar wctype-h
> +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes lstat memchr memmem pathmax readlink rename signal-h strchrnul strstr strtok_r sys_stat unistd update-copyright wchar wctype-h
>
>
>
> @@ -115,6 +115,7 @@ am__aclocal_m4_deps = $(top_srcdir)/import/m4/00gnulib.m4 \
> $(top_srcdir)/import/m4/nocrash.m4 \
> $(top_srcdir)/import/m4/off_t.m4 \
> $(top_srcdir)/import/m4/pathmax.m4 \
> + $(top_srcdir)/import/m4/rawmemchr.m4 \
> $(top_srcdir)/import/m4/readlink.m4 \
> $(top_srcdir)/import/m4/rename.m4 \
> $(top_srcdir)/import/m4/rmdir.m4 \
> @@ -126,6 +127,7 @@ am__aclocal_m4_deps = $(top_srcdir)/import/m4/00gnulib.m4 \
> $(top_srcdir)/import/m4/stdint.m4 \
> $(top_srcdir)/import/m4/stdio_h.m4 \
> $(top_srcdir)/import/m4/stdlib_h.m4 \
> + $(top_srcdir)/import/m4/strchrnul.m4 \
> $(top_srcdir)/import/m4/string_h.m4 \
> $(top_srcdir)/import/m4/strstr.m4 \
> $(top_srcdir)/import/m4/strtok_r.m4 \
> @@ -1277,17 +1279,18 @@ EXTRA_DIST = m4/gnulib-cache.m4 alloca.c alloca.in.h \
> ref-add.sin ref-del.sin lstat.c malloc.c malloca.h \
> malloca.valgrind math.in.h mbrtowc.c mbsinit.c \
> mbsrtowcs-impl.h mbsrtowcs-state.c mbsrtowcs.c memchr.c \
> - memchr.valgrind memmem.c str-two-way.h pathmax.h readlink.c \
> - rename.c rmdir.c same-inode.h signal.in.h \
> - $(top_srcdir)/import/extra/snippet/_Noreturn.h \
> + memchr.valgrind memmem.c str-two-way.h pathmax.h rawmemchr.c \
> + rawmemchr.valgrind readlink.c rename.c rmdir.c same-inode.h \
> + signal.in.h $(top_srcdir)/import/extra/snippet/_Noreturn.h \
> $(top_srcdir)/import/extra/snippet/arg-nonnull.h \
> $(top_srcdir)/import/extra/snippet/c++defs.h \
> $(top_srcdir)/import/extra/snippet/warn-on-use.h stat.c \
> stdbool.in.h stddef.in.h stdint.in.h stdio.in.h stdlib.in.h \
> - streq.h string.in.h str-two-way.h strstr.c strtok_r.c \
> - sys_stat.in.h sys_time.in.h sys_types.in.h time.in.h \
> - unistd.in.h $(top_srcdir)/import/extra/update-copyright \
> - verify.h wchar.in.h wctype.in.h
> + strchrnul.c strchrnul.valgrind streq.h string.in.h \
> + str-two-way.h strstr.c strtok_r.c sys_stat.in.h sys_time.in.h \
> + sys_types.in.h time.in.h unistd.in.h \
> + $(top_srcdir)/import/extra/update-copyright verify.h \
> + wchar.in.h wctype.in.h
>
> # The BUILT_SOURCES created by this Makefile snippet are not used via #include
> # statements but through direct file reference. Therefore this snippet must be
> @@ -1330,8 +1333,8 @@ EXTRA_libgnu_a_SOURCES = alloca.c canonicalize-lgpl.c dirfd.c float.c \
> itold.c fnmatch.c fnmatch_loop.c frexp.c frexp.c frexpl.c \
> gettimeofday.c isnan.c isnand.c isnan.c isnanl.c lstat.c \
> malloc.c mbrtowc.c mbsinit.c mbsrtowcs-state.c mbsrtowcs.c \
> - memchr.c memmem.c readlink.c rename.c rmdir.c stat.c strstr.c \
> - strtok_r.c
> + memchr.c memmem.c rawmemchr.c readlink.c rename.c rmdir.c \
> + stat.c strchrnul.c strstr.c strtok_r.c
>
> # Use this preprocessor expression to decide whether #include_next works.
> # Do not rely on a 'configure'-time test for this, since the expression
> @@ -1432,10 +1435,12 @@ distclean-compile:
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbsrtowcs.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memchr.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memmem.Po@am__quote@
> +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawmemchr.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rename.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmdir.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@
> +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchrnul.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stripslash.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnlen1.Po@am__quote@
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strstr.Po@am__quote@
> diff --git a/gdb/gnulib/import/m4/gnulib-cache.m4 b/gdb/gnulib/import/m4/gnulib-cache.m4
> index a873208..a52dec6 100644
> --- a/gdb/gnulib/import/m4/gnulib-cache.m4
> +++ b/gdb/gnulib/import/m4/gnulib-cache.m4
> @@ -27,7 +27,7 @@
>
>
> # Specification in the form of a command-line invocation:
> -# gnulib-tool --import --dir=. --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes lstat memchr memmem pathmax readlink rename signal-h strstr strtok_r sys_stat unistd update-copyright wchar wctype-h
> +# gnulib-tool --import --dir=. --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes lstat memchr memmem pathmax readlink rename signal-h strchrnul strstr strtok_r sys_stat unistd update-copyright wchar wctype-h
>
> # Specification in the form of a few gnulib-tool.m4 macro invocations:
> gl_LOCAL_DIR([])
> @@ -47,6 +47,7 @@ gl_MODULES([
> readlink
> rename
> signal-h
> + strchrnul
> strstr
> strtok_r
> sys_stat
> diff --git a/gdb/gnulib/import/m4/gnulib-comp.m4 b/gdb/gnulib/import/m4/gnulib-comp.m4
> index 01912bb..235dbb8 100644
> --- a/gdb/gnulib/import/m4/gnulib-comp.m4
> +++ b/gdb/gnulib/import/m4/gnulib-comp.m4
> @@ -83,6 +83,7 @@ AC_DEFUN([gl_EARLY],
> # Code from module multiarch:
> # Code from module nocrash:
> # Code from module pathmax:
> + # Code from module rawmemchr:
> # Code from module readlink:
> # Code from module rename:
> # Code from module rmdir:
> @@ -99,6 +100,7 @@ AC_DEFUN([gl_EARLY],
> # Code from module stdint:
> # Code from module stdio:
> # Code from module stdlib:
> + # Code from module strchrnul:
> # Code from module streq:
> # Code from module string:
> # Code from module strnlen1:
> @@ -251,6 +253,12 @@ AC_DEFUN([gl_INIT],
> gl_STRING_MODULE_INDICATOR([memmem])
> gl_MULTIARCH
> gl_PATHMAX
> + gl_FUNC_RAWMEMCHR
> + if test $HAVE_RAWMEMCHR = 0; then
> + AC_LIBOBJ([rawmemchr])
> + gl_PREREQ_RAWMEMCHR
> + fi
> + gl_STRING_MODULE_INDICATOR([rawmemchr])
> gl_FUNC_READLINK
> if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
> AC_LIBOBJ([readlink])
> @@ -280,6 +288,12 @@ AC_DEFUN([gl_INIT],
> gl_STDINT_H
> gl_STDIO_H
> gl_STDLIB_H
> + gl_FUNC_STRCHRNUL
> + if test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1; then
> + AC_LIBOBJ([strchrnul])
> + gl_PREREQ_STRCHRNUL
> + fi
> + gl_STRING_MODULE_INDICATOR([strchrnul])
> gl_HEADER_STRING_H
> gl_FUNC_STRSTR
> if test $REPLACE_STRSTR = 1; then
> @@ -497,6 +511,8 @@ AC_DEFUN([gl_FILE_LIST], [
> lib/memchr.valgrind
> lib/memmem.c
> lib/pathmax.h
> + lib/rawmemchr.c
> + lib/rawmemchr.valgrind
> lib/readlink.c
> lib/ref-add.sin
> lib/ref-del.sin
> @@ -511,6 +527,8 @@ AC_DEFUN([gl_FILE_LIST], [
> lib/stdio.in.h
> lib/stdlib.in.h
> lib/str-two-way.h
> + lib/strchrnul.c
> + lib/strchrnul.valgrind
> lib/streq.h
> lib/string.in.h
> lib/stripslash.c
> @@ -579,6 +597,7 @@ AC_DEFUN([gl_FILE_LIST], [
> m4/nocrash.m4
> m4/off_t.m4
> m4/pathmax.m4
> + m4/rawmemchr.m4
> m4/readlink.m4
> m4/rename.m4
> m4/rmdir.m4
> @@ -590,6 +609,7 @@ AC_DEFUN([gl_FILE_LIST], [
> m4/stdint.m4
> m4/stdio_h.m4
> m4/stdlib_h.m4
> + m4/strchrnul.m4
> m4/string_h.m4
> m4/strstr.m4
> m4/strtok_r.m4
> diff --git a/gdb/gnulib/import/m4/rawmemchr.m4 b/gdb/gnulib/import/m4/rawmemchr.m4
> new file mode 100644
> index 0000000..88e815e
> --- /dev/null
> +++ b/gdb/gnulib/import/m4/rawmemchr.m4
> @@ -0,0 +1,20 @@
> +# rawmemchr.m4 serial 2
> +dnl Copyright (C) 2003, 2007-2015 Free Software Foundation, Inc.
> +dnl This file is free software; the Free Software Foundation
> +dnl gives unlimited permission to copy and/or distribute it,
> +dnl with or without modifications, as long as this notice is preserved.
> +
> +AC_DEFUN([gl_FUNC_RAWMEMCHR],
> +[
> + dnl Persuade glibc <string.h> to declare rawmemchr().
> + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
> +
> + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
> + AC_CHECK_FUNCS([rawmemchr])
> + if test $ac_cv_func_rawmemchr = no; then
> + HAVE_RAWMEMCHR=0
> + fi
> +])
> +
> +# Prerequisites of lib/strchrnul.c.
> +AC_DEFUN([gl_PREREQ_RAWMEMCHR], [:])
> diff --git a/gdb/gnulib/import/m4/strchrnul.m4 b/gdb/gnulib/import/m4/strchrnul.m4
> new file mode 100644
> index 0000000..8c3d4cf
> --- /dev/null
> +++ b/gdb/gnulib/import/m4/strchrnul.m4
> @@ -0,0 +1,50 @@
> +# strchrnul.m4 serial 9
> +dnl Copyright (C) 2003, 2007, 2009-2015 Free Software Foundation, Inc.
> +dnl This file is free software; the Free Software Foundation
> +dnl gives unlimited permission to copy and/or distribute it,
> +dnl with or without modifications, as long as this notice is preserved.
> +
> +AC_DEFUN([gl_FUNC_STRCHRNUL],
> +[
> + dnl Persuade glibc <string.h> to declare strchrnul().
> + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
> +
> + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
> + AC_CHECK_FUNCS([strchrnul])
> + if test $ac_cv_func_strchrnul = no; then
> + HAVE_STRCHRNUL=0
> + else
> + AC_CACHE_CHECK([whether strchrnul works],
> + [gl_cv_func_strchrnul_works],
> + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
> +#include <string.h> /* for strchrnul */
> +]], [[const char *buf = "a";
> + return strchrnul (buf, 'b') != buf + 1;
> + ]])],
> + [gl_cv_func_strchrnul_works=yes],
> + [gl_cv_func_strchrnul_works=no],
> + [dnl Cygwin 1.7.9 introduced strchrnul, but it was broken until 1.7.10
> + AC_EGREP_CPP([Lucky user],
> + [
> +#if defined __CYGWIN__
> + #include <cygwin/version.h>
> + #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 9)
> + Lucky user
> + #endif
> +#else
> + Lucky user
> +#endif
> + ],
> + [gl_cv_func_strchrnul_works="guessing yes"],
> + [gl_cv_func_strchrnul_works="guessing no"])
> + ])
> + ])
> + case "$gl_cv_func_strchrnul_works" in
> + *yes) ;;
> + *) REPLACE_STRCHRNUL=1 ;;
> + esac
> + fi
> +])
> +
> +# Prerequisites of lib/strchrnul.c.
> +AC_DEFUN([gl_PREREQ_STRCHRNUL], [:])
> diff --git a/gdb/gnulib/import/rawmemchr.c b/gdb/gnulib/import/rawmemchr.c
> new file mode 100644
> index 0000000..a6380ba
> --- /dev/null
> +++ b/gdb/gnulib/import/rawmemchr.c
> @@ -0,0 +1,136 @@
> +/* Searching in a string.
> + Copyright (C) 2008-2015 Free Software Foundation, Inc.
> +
> + This program is free software: you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +#include <config.h>
> +
> +/* Specification. */
> +#include <string.h>
> +
> +/* Find the first occurrence of C in S. */
> +void *
> +rawmemchr (const void *s, int c_in)
> +{
> + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
> + long instead of a 64-bit uintmax_t tends to give better
> + performance. On 64-bit hardware, unsigned long is generally 64
> + bits already. Change this typedef to experiment with
> + performance. */
> + typedef unsigned long int longword;
> +
> + const unsigned char *char_ptr;
> + const longword *longword_ptr;
> + longword repeated_one;
> + longword repeated_c;
> + unsigned char c;
> +
> + c = (unsigned char) c_in;
> +
> + /* Handle the first few bytes by reading one byte at a time.
> + Do this until CHAR_PTR is aligned on a longword boundary. */
> + for (char_ptr = (const unsigned char *) s;
> + (size_t) char_ptr % sizeof (longword) != 0;
> + ++char_ptr)
> + if (*char_ptr == c)
> + return (void *) char_ptr;
> +
> + longword_ptr = (const longword *) char_ptr;
> +
> + /* All these elucidatory comments refer to 4-byte longwords,
> + but the theory applies equally well to any size longwords. */
> +
> + /* Compute auxiliary longword values:
> + repeated_one is a value which has a 1 in every byte.
> + repeated_c has c in every byte. */
> + repeated_one = 0x01010101;
> + repeated_c = c | (c << 8);
> + repeated_c |= repeated_c << 16;
> + if (0xffffffffU < (longword) -1)
> + {
> + repeated_one |= repeated_one << 31 << 1;
> + repeated_c |= repeated_c << 31 << 1;
> + if (8 < sizeof (longword))
> + {
> + size_t i;
> +
> + for (i = 64; i < sizeof (longword) * 8; i *= 2)
> + {
> + repeated_one |= repeated_one << i;
> + repeated_c |= repeated_c << i;
> + }
> + }
> + }
> +
> + /* Instead of the traditional loop which tests each byte, we will
> + test a longword at a time. The tricky part is testing if *any of
> + the four* bytes in the longword in question are equal to NUL or
> + c. We first use an xor with repeated_c. This reduces the task
> + to testing whether *any of the four* bytes in longword1 is zero.
> +
> + We compute tmp =
> + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
> + That is, we perform the following operations:
> + 1. Subtract repeated_one.
> + 2. & ~longword1.
> + 3. & a mask consisting of 0x80 in every byte.
> + Consider what happens in each byte:
> + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
> + and step 3 transforms it into 0x80. A carry can also be propagated
> + to more significant bytes.
> + - If a byte of longword1 is nonzero, let its lowest 1 bit be at
> + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
> + the byte ends in a single bit of value 0 and k bits of value 1.
> + After step 2, the result is just k bits of value 1: 2^k - 1. After
> + step 3, the result is 0. And no carry is produced.
> + So, if longword1 has only non-zero bytes, tmp is zero.
> + Whereas if longword1 has a zero byte, call j the position of the least
> + significant zero byte. Then the result has a zero at positions 0, ...,
> + j-1 and a 0x80 at position j. We cannot predict the result at the more
> + significant bytes (positions j+1..3), but it does not matter since we
> + already have a non-zero bit at position 8*j+7.
> +
> + The test whether any byte in longword1 is zero is equivalent
> + to testing whether tmp is nonzero.
> +
> + This test can read beyond the end of a string, depending on where
> + C_IN is encountered. However, this is considered safe since the
> + initialization phase ensured that the read will be aligned,
> + therefore, the read will not cross page boundaries and will not
> + cause a fault. */
> +
> + while (1)
> + {
> + longword longword1 = *longword_ptr ^ repeated_c;
> +
> + if ((((longword1 - repeated_one) & ~longword1)
> + & (repeated_one << 7)) != 0)
> + break;
> + longword_ptr++;
> + }
> +
> + char_ptr = (const unsigned char *) longword_ptr;
> +
> + /* At this point, we know that one of the sizeof (longword) bytes
> + starting at char_ptr is == c. On little-endian machines, we
> + could determine the first such byte without any further memory
> + accesses, just by looking at the tmp result from the last loop
> + iteration. But this does not work on big-endian machines.
> + Choose code that works in both cases. */
> +
> + char_ptr = (unsigned char *) longword_ptr;
> + while (*char_ptr != c)
> + char_ptr++;
> + return (void *) char_ptr;
> +}
> diff --git a/gdb/gnulib/import/rawmemchr.valgrind b/gdb/gnulib/import/rawmemchr.valgrind
> new file mode 100644
> index 0000000..6363923
> --- /dev/null
> +++ b/gdb/gnulib/import/rawmemchr.valgrind
> @@ -0,0 +1,12 @@
> +# Suppress a valgrind message about use of uninitialized memory in rawmemchr().
> +# This use is OK because it provides only a speedup.
> +{
> + rawmemchr-value4
> + Memcheck:Value4
> + fun:rawmemchr
> +}
> +{
> + rawmemchr-value8
> + Memcheck:Value8
> + fun:rawmemchr
> +}
> diff --git a/gdb/gnulib/import/strchrnul.c b/gdb/gnulib/import/strchrnul.c
> new file mode 100644
> index 0000000..1000e83
> --- /dev/null
> +++ b/gdb/gnulib/import/strchrnul.c
> @@ -0,0 +1,142 @@
> +/* Searching in a string.
> + Copyright (C) 2003, 2007-2015 Free Software Foundation, Inc.
> +
> + This program is free software: you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +#include <config.h>
> +
> +/* Specification. */
> +#include <string.h>
> +
> +/* Find the first occurrence of C in S or the final NUL byte. */
> +char *
> +strchrnul (const char *s, int c_in)
> +{
> + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
> + long instead of a 64-bit uintmax_t tends to give better
> + performance. On 64-bit hardware, unsigned long is generally 64
> + bits already. Change this typedef to experiment with
> + performance. */
> + typedef unsigned long int longword;
> +
> + const unsigned char *char_ptr;
> + const longword *longword_ptr;
> + longword repeated_one;
> + longword repeated_c;
> + unsigned char c;
> +
> + c = (unsigned char) c_in;
> + if (!c)
> + return rawmemchr (s, 0);
> +
> + /* Handle the first few bytes by reading one byte at a time.
> + Do this until CHAR_PTR is aligned on a longword boundary. */
> + for (char_ptr = (const unsigned char *) s;
> + (size_t) char_ptr % sizeof (longword) != 0;
> + ++char_ptr)
> + if (!*char_ptr || *char_ptr == c)
> + return (char *) char_ptr;
> +
> + longword_ptr = (const longword *) char_ptr;
> +
> + /* All these elucidatory comments refer to 4-byte longwords,
> + but the theory applies equally well to any size longwords. */
> +
> + /* Compute auxiliary longword values:
> + repeated_one is a value which has a 1 in every byte.
> + repeated_c has c in every byte. */
> + repeated_one = 0x01010101;
> + repeated_c = c | (c << 8);
> + repeated_c |= repeated_c << 16;
> + if (0xffffffffU < (longword) -1)
> + {
> + repeated_one |= repeated_one << 31 << 1;
> + repeated_c |= repeated_c << 31 << 1;
> + if (8 < sizeof (longword))
> + {
> + size_t i;
> +
> + for (i = 64; i < sizeof (longword) * 8; i *= 2)
> + {
> + repeated_one |= repeated_one << i;
> + repeated_c |= repeated_c << i;
> + }
> + }
> + }
> +
> + /* Instead of the traditional loop which tests each byte, we will
> + test a longword at a time. The tricky part is testing if *any of
> + the four* bytes in the longword in question are equal to NUL or
> + c. We first use an xor with repeated_c. This reduces the task
> + to testing whether *any of the four* bytes in longword1 or
> + longword2 is zero.
> +
> + Let's consider longword1. We compute tmp =
> + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
> + That is, we perform the following operations:
> + 1. Subtract repeated_one.
> + 2. & ~longword1.
> + 3. & a mask consisting of 0x80 in every byte.
> + Consider what happens in each byte:
> + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
> + and step 3 transforms it into 0x80. A carry can also be propagated
> + to more significant bytes.
> + - If a byte of longword1 is nonzero, let its lowest 1 bit be at
> + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
> + the byte ends in a single bit of value 0 and k bits of value 1.
> + After step 2, the result is just k bits of value 1: 2^k - 1. After
> + step 3, the result is 0. And no carry is produced.
> + So, if longword1 has only non-zero bytes, tmp is zero.
> + Whereas if longword1 has a zero byte, call j the position of the least
> + significant zero byte. Then the result has a zero at positions 0, ...,
> + j-1 and a 0x80 at position j. We cannot predict the result at the more
> + significant bytes (positions j+1..3), but it does not matter since we
> + already have a non-zero bit at position 8*j+7.
> +
> + The test whether any byte in longword1 or longword2 is zero is equivalent
> + to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine
> + this into a single test, whether (tmp1 | tmp2) is nonzero.
> +
> + This test can read more than one byte beyond the end of a string,
> + depending on where the terminating NUL is encountered. However,
> + this is considered safe since the initialization phase ensured
> + that the read will be aligned, therefore, the read will not cross
> + page boundaries and will not cause a fault. */
> +
> + while (1)
> + {
> + longword longword1 = *longword_ptr ^ repeated_c;
> + longword longword2 = *longword_ptr;
> +
> + if (((((longword1 - repeated_one) & ~longword1)
> + | ((longword2 - repeated_one) & ~longword2))
> + & (repeated_one << 7)) != 0)
> + break;
> + longword_ptr++;
> + }
> +
> + char_ptr = (const unsigned char *) longword_ptr;
> +
> + /* At this point, we know that one of the sizeof (longword) bytes
> + starting at char_ptr is == 0 or == c. On little-endian machines,
> + we could determine the first such byte without any further memory
> + accesses, just by looking at the tmp result from the last loop
> + iteration. But this does not work on big-endian machines.
> + Choose code that works in both cases. */
> +
> + char_ptr = (unsigned char *) longword_ptr;
> + while (*char_ptr && (*char_ptr != c))
> + char_ptr++;
> + return (char *) char_ptr;
> +}
> diff --git a/gdb/gnulib/import/strchrnul.valgrind b/gdb/gnulib/import/strchrnul.valgrind
> new file mode 100644
> index 0000000..b14fa13
> --- /dev/null
> +++ b/gdb/gnulib/import/strchrnul.valgrind
> @@ -0,0 +1,12 @@
> +# Suppress a valgrind message about use of uninitialized memory in strchrnul().
> +# This use is OK because it provides only a speedup.
> +{
> + strchrnul-value4
> + Memcheck:Value4
> + fun:strchrnul
> +}
> +{
> + strchrnul-value8
> + Memcheck:Value8
> + fun:strchrnul
> +}
> diff --git a/gdb/gnulib/update-gnulib.sh b/gdb/gnulib/update-gnulib.sh
> index 5d42f98..07de4c6 100755
> --- a/gdb/gnulib/update-gnulib.sh
> +++ b/gdb/gnulib/update-gnulib.sh
> @@ -45,6 +45,7 @@ IMPORTED_GNULIB_MODULES="\
> readlink \
> rename \
> signal-h \
> + strchrnul \
> strstr \
> strtok_r \
> sys_stat \
> diff --git a/gdb/remote.c b/gdb/remote.c
> index b0303f6..8831b50 100644
> --- a/gdb/remote.c
> +++ b/gdb/remote.c
> @@ -6387,16 +6387,6 @@ peek_stop_reply (ptid_t ptid)
> stop_reply_match_ptid_and_ws, &ptid);
> }
>
> -/* Skip PACKET until the next semi-colon (or end of string). */
> -
> -static char *
> -skip_to_semicolon (char *p)
> -{
> - while (*p != '\0' && *p != ';')
> - p++;
> - return p;
> -}
> -
> /* Helper for remote_parse_stop_reply. Return nonzero if the substring
> starting with P and ending with PEND matches PREFIX. */
>
> @@ -6499,7 +6489,7 @@ Packet: '%s'\n"),
> /* The value part is documented as "must be empty",
> though we ignore it, in case we ever decide to make
> use of it in a backward compatible way. */
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> else if (strprefix (p, p1, "hwbreak"))
> {
> @@ -6511,19 +6501,19 @@ Packet: '%s'\n"),
> error (_("Unexpected hwbreak stop reason"));
>
> /* See above. */
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> else if (strprefix (p, p1, "library"))
> {
> event->ws.kind = TARGET_WAITKIND_LOADED;
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> else if (strprefix (p, p1, "replaylog"))
> {
> event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
> /* p1 will indicate "begin" or "end", but it makes
> no difference for now, so ignore it. */
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> else if (strprefix (p, p1, "core"))
> {
> @@ -6545,7 +6535,7 @@ Packet: '%s'\n"),
> else if (strprefix (p, p1, "vforkdone"))
> {
> event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> else if (strprefix (p, p1, "exec"))
> {
> @@ -6574,7 +6564,7 @@ Packet: '%s'\n"),
> else if (strprefix (p, p1, "create"))
> {
> event->ws.kind = TARGET_WAITKIND_THREAD_CREATED;
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> else
> {
> @@ -6583,7 +6573,7 @@ Packet: '%s'\n"),
>
> if (skipregs)
> {
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> p++;
> continue;
> }
> @@ -6620,7 +6610,7 @@ Packet: '%s'\n"),
> {
> /* Not a number. Silently skip unknown optional
> info. */
> - p = skip_to_semicolon (p1 + 1);
> + p = strchrnul (p1 + 1, ';');
> }
> }
>
> --
> 2.5.1
--
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF 31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/