This patch is inspired by Adhemerval Zanella's recent proposal https://www.sourceware.org/ml/libc-alpha/2018-06/msg00905.html to merge glibc and Gnulib regex. It aims to simplify the merge on the glibc side, without keeping Gnulib portable. * lib/regex.h: Fix a problem with glibc installed-header checking, as follows: (_Restrict_): Prefer __restrict if defined or if GCC 2.95 or later. (_Restrict_arr_): Prefer __restrict_arr if defined, otherwise prefer _Restrict_ if C99 or GCC 3.1 or later (but not C++). * lib/regex_internal.c (re_string_realloc_buffers, build_wcs_buffer) (build_wcs_upper_buffer, build_upper_buffer) (re_string_translate_buffer, re_string_context_at): Move decls here from lib/regex_internal.h, for glibc internal tests. (build_wcs_upper_buffer): Use __wcrtomb, not wcrtomb, fixing glibc BZ #18496. * lib/regex_internal.h (lock_fini) [_LIBC]: Cast to 0 to pacify -Wunused-value. (bitset_set, bitset_clear, bitset_contain, bitset_empty) (bitset_set_all, bitset_copy, bitset_not, bitset_merge) (bitset_mask): Now static inline, and without any __attribute__ ((unused)) decoration, for glibc internal tests. --- ChangeLog | 25 +++++++++++++++++++++++++ lib/regex.h | 25 ++++++++++++------------- lib/regex_internal.c | 12 +++++++++++- lib/regex_internal.h | 31 ++++++++++--------------------- 4 files changed, 58 insertions(+), 35 deletions(-)
diff --git a/ChangeLog b/ChangeLog index a356a4086..1b2505a1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2018-06-28 Paul Eggert <egg...@cs.ucla.edu> + + regex: port to recently proposed glibc regex merge + This patch is inspired by Adhemerval Zanella's recent proposal + https://www.sourceware.org/ml/libc-alpha/2018-06/msg00905.html + to merge glibc and Gnulib regex. It aims to simplify the merge on + the glibc side, without keeping Gnulib portable. + * lib/regex.h: Fix a problem with glibc installed-header checking, + as follows: + (_Restrict_): Prefer __restrict if defined or if GCC 2.95 or later. + (_Restrict_arr_): Prefer __restrict_arr if defined, + otherwise prefer _Restrict_ if C99 or GCC 3.1 or later (but not C++). + * lib/regex_internal.c (re_string_realloc_buffers, build_wcs_buffer) + (build_wcs_upper_buffer, build_upper_buffer) + (re_string_translate_buffer, re_string_context_at): + Move decls here from lib/regex_internal.h, for glibc internal tests. + (build_wcs_upper_buffer): Use __wcrtomb, not wcrtomb, fixing + glibc BZ #18496. + * lib/regex_internal.h (lock_fini) [_LIBC]: Cast to 0 to pacify + -Wunused-value. + (bitset_set, bitset_clear, bitset_contain, bitset_empty) + (bitset_set_all, bitset_copy, bitset_not, bitset_merge) + (bitset_mask): Now static inline, and without any __attribute__ + ((unused)) decoration, for glibc internal tests. + 2018-06-25 Bruno Haible <br...@clisp.org> threadlib: Fix LIBMULTITHREAD on platforms where --as-needed is enabled. diff --git a/lib/regex.h b/lib/regex.h index 9ed74c3df..32933bc6d 100644 --- a/lib/regex.h +++ b/lib/regex.h @@ -1,7 +1,6 @@ /* Definitions for data structures and routines for the regular expression library. - Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2018 Free Software - Foundation, Inc. + Copyright (C) 1985, 1989-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -608,28 +607,28 @@ extern int re_exec (const char *); # endif #endif -/* GCC 2.95 and later have "__restrict"; C99 compilers have +/* For plain 'restrict', use glibc's __restrict if defined. + Otherwise, GCC 2.95 and later have "__restrict"; C99 compilers have "restrict", and "configure" may have defined "restrict". Other compilers use __restrict, __restrict__, and _Restrict, and 'configure' might #define 'restrict' to those words, so pick a different name. */ #ifndef _Restrict_ -# if 199901L <= __STDC_VERSION__ -# define _Restrict_ restrict -# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) +# if defined __restrict || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) # define _Restrict_ __restrict +# elif 199901L <= __STDC_VERSION__ || defined restrict +# define _Restrict_ restrict # else # define _Restrict_ # endif #endif -/* gcc 3.1 and up support the [restrict] syntax. Don't trust - sys/cdefs.h's definition of __restrict_arr, though, as it - mishandles gcc -ansi -pedantic. */ +/* For [restrict], use glibc's __restrict_arr if available. + Otherwise, GCC 3.1 (not in C++ mode) and C99 support [restrict]. */ #ifndef _Restrict_arr_ -# if ((199901L <= __STDC_VERSION__ \ - || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ - && !defined __STRICT_ANSI__)) \ - && !defined __GNUG__) +# ifdef __restrict_arr +# define _Restrict_arr_ __restrict_arr +# elif ((199901L <= __STDC_VERSION__ || 3 < __GNUC__ + (1 <= __GNUC_MINOR__)) \ + && !defined __GNUG__) # define _Restrict_arr_ _Restrict_ # else # define _Restrict_arr_ diff --git a/lib/regex_internal.c b/lib/regex_internal.c index c08c8e465..7f0083b91 100644 --- a/lib/regex_internal.c +++ b/lib/regex_internal.c @@ -28,6 +28,16 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context, re_hashval_t hash); +static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, + Idx new_buf_len); +#ifdef RE_ENABLE_I18N +static void build_wcs_buffer (re_string_t *pstr); +static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr); +#endif /* RE_ENABLE_I18N */ +static void build_upper_buffer (re_string_t *pstr); +static void re_string_translate_buffer (re_string_t *pstr); +static unsigned int re_string_context_at (const re_string_t *input, Idx idx, + int eflags) __attribute__ ((pure)); /* Functions for string operation. */ @@ -383,7 +393,7 @@ build_wcs_upper_buffer (re_string_t *pstr) { size_t mbcdlen; - mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); + mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st); if (BE (mbclen == mbcdlen, 1)) memcpy (pstr->mbs + byte_idx, buf, mbclen); else if (mbcdlen != (size_t) -1) diff --git a/lib/regex_internal.h b/lib/regex_internal.h index bc7c600a3..b27afbda2 100644 --- a/lib/regex_internal.h +++ b/lib/regex_internal.h @@ -39,7 +39,7 @@ # include <libc-lock.h> # define lock_define(name) __libc_lock_define (, name) # define lock_init(lock) (__libc_lock_init (lock), 0) -# define lock_fini(lock) 0 +# define lock_fini(lock) ((void) 0) # define lock_lock(lock) __libc_lock_lock (lock) # define lock_unlock(lock) __libc_lock_unlock (lock) #elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO @@ -441,17 +441,6 @@ typedef struct re_dfa_t re_dfa_t; # define IS_IN(libc) false #endif -static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, - Idx new_buf_len); -#ifdef RE_ENABLE_I18N -static void build_wcs_buffer (re_string_t *pstr); -static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr); -#endif /* RE_ENABLE_I18N */ -static void build_upper_buffer (re_string_t *pstr); -static void re_string_translate_buffer (re_string_t *pstr); -static unsigned int re_string_context_at (const re_string_t *input, Idx idx, - int eflags) __attribute__ ((pure)); - #define re_string_peek_byte(pstr, offset) \ ((pstr)->mbs[(pstr)->cur_idx + offset]) #define re_string_fetch_byte(pstr) \ @@ -757,31 +746,31 @@ typedef struct /* Functions for bitset_t operation. */ -static void +static inline void bitset_set (bitset_t set, Idx i) { set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; } -static void +static inline void bitset_clear (bitset_t set, Idx i) { set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); } -static bool +static inline bool bitset_contain (const bitset_t set, Idx i) { return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; } -static void +static inline void bitset_empty (bitset_t set) { memset (set, '\0', sizeof (bitset_t)); } -static void +static inline void bitset_set_all (bitset_t set) { memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); @@ -790,13 +779,13 @@ bitset_set_all (bitset_t set) ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; } -static void +static inline void bitset_copy (bitset_t dest, const bitset_t src) { memcpy (dest, src, sizeof (bitset_t)); } -static void __attribute__ ((unused)) +static inline void bitset_not (bitset_t set) { int bitset_i; @@ -808,7 +797,7 @@ bitset_not (bitset_t set) & ~set[BITSET_WORDS - 1]); } -static void __attribute__ ((unused)) +static inline void bitset_merge (bitset_t dest, const bitset_t src) { int bitset_i; @@ -816,7 +805,7 @@ bitset_merge (bitset_t dest, const bitset_t src) dest[bitset_i] |= src[bitset_i]; } -static void __attribute__ ((unused)) +static inline void bitset_mask (bitset_t dest, const bitset_t src) { int bitset_i; -- 2.17.1