summaryrefslogtreecommitdiffstats
path: root/gl/regex_internal.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2023-02-11 07:20:24 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2023-02-11 07:20:24 +0100
commitf867d7b44080fa9716deeff4476275f9a489879f (patch)
treebc964662fc3300dc626fb6d833d8ed5c8f46eca7 /gl/regex_internal.c
parent9734c439cba0a02b087e50789e94ec9b07754608 (diff)
parentc07206f2ccc2356aa74bc6813a94c2190017d44e (diff)
downloadmonitoring-plugins-f867d7b.tar.gz
Merge branch 'master' into curlfixes
Diffstat (limited to 'gl/regex_internal.c')
-rw-r--r--gl/regex_internal.c394
1 files changed, 182 insertions, 212 deletions
diff --git a/gl/regex_internal.c b/gl/regex_internal.c
index 899b0ae6..998a19b7 100644
--- a/gl/regex_internal.c
+++ b/gl/regex_internal.c
@@ -1,33 +1,41 @@
1/* Extended regular expression matching and search library. 1/* Extended regular expression matching and search library.
2 Copyright (C) 2002-2013 Free Software Foundation, Inc. 2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. 4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public 7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 3 of the License, or (at your option) any later version. 9 version 2.1 of the License, or (at your option) any later version.
10 10
11 The GNU C Library is distributed in the hope that it will be useful, 11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 Lesser General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public 16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see 17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */ 18 <https://www.gnu.org/licenses/>. */
19 19
20static void re_string_construct_common (const char *str, Idx len, 20static void re_string_construct_common (const char *str, Idx len,
21 re_string_t *pstr, 21 re_string_t *pstr,
22 RE_TRANSLATE_TYPE trans, bool icase, 22 RE_TRANSLATE_TYPE trans, bool icase,
23 const re_dfa_t *dfa) internal_function; 23 const re_dfa_t *dfa);
24static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, 24static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
25 const re_node_set *nodes, 25 const re_node_set *nodes,
26 re_hashval_t hash) internal_function; 26 re_hashval_t hash);
27static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, 27static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
28 const re_node_set *nodes, 28 const re_node_set *nodes,
29 unsigned int context, 29 unsigned int context,
30 re_hashval_t hash) internal_function; 30 re_hashval_t hash);
31static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
32 Idx new_buf_len);
33static void build_wcs_buffer (re_string_t *pstr);
34static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr);
35static void build_upper_buffer (re_string_t *pstr);
36static void re_string_translate_buffer (re_string_t *pstr);
37static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
38 int eflags) __attribute__ ((pure));
31 39
32/* Functions for string operation. */ 40/* Functions for string operation. */
33 41
@@ -35,7 +43,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
35 re_string_reconstruct before using the object. */ 43 re_string_reconstruct before using the object. */
36 44
37static reg_errcode_t 45static reg_errcode_t
38internal_function __attribute_warn_unused_result__ 46__attribute_warn_unused_result__
39re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, 47re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
40 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) 48 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
41{ 49{
@@ -49,7 +57,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
49 re_string_construct_common (str, len, pstr, trans, icase, dfa); 57 re_string_construct_common (str, len, pstr, trans, icase, dfa);
50 58
51 ret = re_string_realloc_buffers (pstr, init_buf_len); 59 ret = re_string_realloc_buffers (pstr, init_buf_len);
52 if (BE (ret != REG_NOERROR, 0)) 60 if (__glibc_unlikely (ret != REG_NOERROR))
53 return ret; 61 return ret;
54 62
55 pstr->word_char = dfa->word_char; 63 pstr->word_char = dfa->word_char;
@@ -63,7 +71,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
63/* This function allocate the buffers, and initialize them. */ 71/* This function allocate the buffers, and initialize them. */
64 72
65static reg_errcode_t 73static reg_errcode_t
66internal_function __attribute_warn_unused_result__ 74__attribute_warn_unused_result__
67re_string_construct (re_string_t *pstr, const char *str, Idx len, 75re_string_construct (re_string_t *pstr, const char *str, Idx len,
68 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) 76 RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
69{ 77{
@@ -74,41 +82,37 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
74 if (len > 0) 82 if (len > 0)
75 { 83 {
76 ret = re_string_realloc_buffers (pstr, len + 1); 84 ret = re_string_realloc_buffers (pstr, len + 1);
77 if (BE (ret != REG_NOERROR, 0)) 85 if (__glibc_unlikely (ret != REG_NOERROR))
78 return ret; 86 return ret;
79 } 87 }
80 pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; 88 pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
81 89
82 if (icase) 90 if (icase)
83 { 91 {
84#ifdef RE_ENABLE_I18N
85 if (dfa->mb_cur_max > 1) 92 if (dfa->mb_cur_max > 1)
86 { 93 {
87 while (1) 94 while (1)
88 { 95 {
89 ret = build_wcs_upper_buffer (pstr); 96 ret = build_wcs_upper_buffer (pstr);
90 if (BE (ret != REG_NOERROR, 0)) 97 if (__glibc_unlikely (ret != REG_NOERROR))
91 return ret; 98 return ret;
92 if (pstr->valid_raw_len >= len) 99 if (pstr->valid_raw_len >= len)
93 break; 100 break;
94 if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) 101 if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
95 break; 102 break;
96 ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); 103 ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
97 if (BE (ret != REG_NOERROR, 0)) 104 if (__glibc_unlikely (ret != REG_NOERROR))
98 return ret; 105 return ret;
99 } 106 }
100 } 107 }
101 else 108 else
102#endif /* RE_ENABLE_I18N */
103 build_upper_buffer (pstr); 109 build_upper_buffer (pstr);
104 } 110 }
105 else 111 else
106 { 112 {
107#ifdef RE_ENABLE_I18N
108 if (dfa->mb_cur_max > 1) 113 if (dfa->mb_cur_max > 1)
109 build_wcs_buffer (pstr); 114 build_wcs_buffer (pstr);
110 else 115 else
111#endif /* RE_ENABLE_I18N */
112 { 116 {
113 if (trans != NULL) 117 if (trans != NULL)
114 re_string_translate_buffer (pstr); 118 re_string_translate_buffer (pstr);
@@ -126,37 +130,36 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
126/* Helper functions for re_string_allocate, and re_string_construct. */ 130/* Helper functions for re_string_allocate, and re_string_construct. */
127 131
128static reg_errcode_t 132static reg_errcode_t
129internal_function __attribute_warn_unused_result__ 133__attribute_warn_unused_result__
130re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) 134re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
131{ 135{
132#ifdef RE_ENABLE_I18N
133 if (pstr->mb_cur_max > 1) 136 if (pstr->mb_cur_max > 1)
134 { 137 {
135 wint_t *new_wcs; 138 wint_t *new_wcs;
136 139
137 /* Avoid overflow in realloc. */ 140 /* Avoid overflow in realloc. */
138 const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); 141 const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
139 if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_buf_len, 0)) 142 if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
143 < new_buf_len))
140 return REG_ESPACE; 144 return REG_ESPACE;
141 145
142 new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); 146 new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
143 if (BE (new_wcs == NULL, 0)) 147 if (__glibc_unlikely (new_wcs == NULL))
144 return REG_ESPACE; 148 return REG_ESPACE;
145 pstr->wcs = new_wcs; 149 pstr->wcs = new_wcs;
146 if (pstr->offsets != NULL) 150 if (pstr->offsets != NULL)
147 { 151 {
148 Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); 152 Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
149 if (BE (new_offsets == NULL, 0)) 153 if (__glibc_unlikely (new_offsets == NULL))
150 return REG_ESPACE; 154 return REG_ESPACE;
151 pstr->offsets = new_offsets; 155 pstr->offsets = new_offsets;
152 } 156 }
153 } 157 }
154#endif /* RE_ENABLE_I18N */
155 if (pstr->mbs_allocated) 158 if (pstr->mbs_allocated)
156 { 159 {
157 unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, 160 unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
158 new_buf_len); 161 new_buf_len);
159 if (BE (new_mbs == NULL, 0)) 162 if (__glibc_unlikely (new_mbs == NULL))
160 return REG_ESPACE; 163 return REG_ESPACE;
161 pstr->mbs = new_mbs; 164 pstr->mbs = new_mbs;
162 } 165 }
@@ -166,7 +169,6 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
166 169
167 170
168static void 171static void
169internal_function
170re_string_construct_common (const char *str, Idx len, re_string_t *pstr, 172re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
171 RE_TRANSLATE_TYPE trans, bool icase, 173 RE_TRANSLATE_TYPE trans, bool icase,
172 const re_dfa_t *dfa) 174 const re_dfa_t *dfa)
@@ -184,7 +186,6 @@ re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
184 pstr->raw_stop = pstr->stop; 186 pstr->raw_stop = pstr->stop;
185} 187}
186 188
187#ifdef RE_ENABLE_I18N
188 189
189/* Build wide character buffer PSTR->WCS. 190/* Build wide character buffer PSTR->WCS.
190 If the byte sequence of the string are: 191 If the byte sequence of the string are:
@@ -198,12 +199,11 @@ re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
198 built and starts from PSTR->VALID_LEN. */ 199 built and starts from PSTR->VALID_LEN. */
199 200
200static void 201static void
201internal_function
202build_wcs_buffer (re_string_t *pstr) 202build_wcs_buffer (re_string_t *pstr)
203{ 203{
204#ifdef _LIBC 204#ifdef _LIBC
205 unsigned char buf[MB_LEN_MAX]; 205 unsigned char buf[MB_LEN_MAX];
206 assert (MB_LEN_MAX >= pstr->mb_cur_max); 206 DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max);
207#else 207#else
208 unsigned char buf[64]; 208 unsigned char buf[64];
209#endif 209#endif
@@ -222,7 +222,7 @@ build_wcs_buffer (re_string_t *pstr)
222 remain_len = end_idx - byte_idx; 222 remain_len = end_idx - byte_idx;
223 prev_st = pstr->cur_state; 223 prev_st = pstr->cur_state;
224 /* Apply the translation if we need. */ 224 /* Apply the translation if we need. */
225 if (BE (pstr->trans != NULL, 0)) 225 if (__glibc_unlikely (pstr->trans != NULL))
226 { 226 {
227 int i, ch; 227 int i, ch;
228 228
@@ -236,17 +236,18 @@ build_wcs_buffer (re_string_t *pstr)
236 else 236 else
237 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; 237 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
238 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); 238 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
239 if (BE (mbclen == (size_t) -1 || mbclen == 0 239 if (__glibc_unlikely (mbclen == (size_t) -1 || mbclen == 0
240 || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0)) 240 || (mbclen == (size_t) -2
241 && pstr->bufs_len >= pstr->len)))
241 { 242 {
242 /* We treat these cases as a singlebyte character. */ 243 /* We treat these cases as a singlebyte character. */
243 mbclen = 1; 244 mbclen = 1;
244 wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; 245 wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
245 if (BE (pstr->trans != NULL, 0)) 246 if (__glibc_unlikely (pstr->trans != NULL))
246 wc = pstr->trans[wc]; 247 wc = pstr->trans[wc];
247 pstr->cur_state = prev_st; 248 pstr->cur_state = prev_st;
248 } 249 }
249 else if (BE (mbclen == (size_t) -2, 0)) 250 else if (__glibc_unlikely (mbclen == (size_t) -2))
250 { 251 {
251 /* The buffer doesn't have enough space, finish to build. */ 252 /* The buffer doesn't have enough space, finish to build. */
252 pstr->cur_state = prev_st; 253 pstr->cur_state = prev_st;
@@ -267,7 +268,7 @@ build_wcs_buffer (re_string_t *pstr)
267 but for REG_ICASE. */ 268 but for REG_ICASE. */
268 269
269static reg_errcode_t 270static reg_errcode_t
270internal_function __attribute_warn_unused_result__ 271__attribute_warn_unused_result__
271build_wcs_upper_buffer (re_string_t *pstr) 272build_wcs_upper_buffer (re_string_t *pstr)
272{ 273{
273 mbstate_t prev_st; 274 mbstate_t prev_st;
@@ -275,7 +276,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
275 size_t mbclen; 276 size_t mbclen;
276#ifdef _LIBC 277#ifdef _LIBC
277 char buf[MB_LEN_MAX]; 278 char buf[MB_LEN_MAX];
278 assert (MB_LEN_MAX >= pstr->mb_cur_max); 279 DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX);
279#else 280#else
280 char buf[64]; 281 char buf[64];
281#endif 282#endif
@@ -290,18 +291,20 @@ build_wcs_upper_buffer (re_string_t *pstr)
290 while (byte_idx < end_idx) 291 while (byte_idx < end_idx)
291 { 292 {
292 wchar_t wc; 293 wchar_t wc;
294 unsigned char ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
293 295
294 if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) 296 if (isascii (ch) && mbsinit (&pstr->cur_state))
295 && mbsinit (&pstr->cur_state))
296 { 297 {
297 /* In case of a singlebyte character. */
298 pstr->mbs[byte_idx]
299 = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
300 /* The next step uses the assumption that wchar_t is encoded 298 /* The next step uses the assumption that wchar_t is encoded
301 ASCII-safe: all ASCII values can be converted like this. */ 299 ASCII-safe: all ASCII values can be converted like this. */
302 pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; 300 wchar_t wcu = __towupper (ch);
303 ++byte_idx; 301 if (isascii (wcu))
304 continue; 302 {
303 pstr->mbs[byte_idx] = wcu;
304 pstr->wcs[byte_idx] = wcu;
305 byte_idx++;
306 continue;
307 }
305 } 308 }
306 309
307 remain_len = end_idx - byte_idx; 310 remain_len = end_idx - byte_idx;
@@ -309,16 +312,15 @@ build_wcs_upper_buffer (re_string_t *pstr)
309 mbclen = __mbrtowc (&wc, 312 mbclen = __mbrtowc (&wc,
310 ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx 313 ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
311 + byte_idx), remain_len, &pstr->cur_state); 314 + byte_idx), remain_len, &pstr->cur_state);
312 if (BE (mbclen < (size_t) -2, 1)) 315 if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
313 { 316 {
314 wchar_t wcu = wc; 317 wchar_t wcu = __towupper (wc);
315 if (iswlower (wc)) 318 if (wcu != wc)
316 { 319 {
317 size_t mbcdlen; 320 size_t mbcdlen;
318 321
319 wcu = towupper (wc); 322 mbcdlen = __wcrtomb (buf, wcu, &prev_st);
320 mbcdlen = wcrtomb (buf, wcu, &prev_st); 323 if (__glibc_likely (mbclen == mbcdlen))
321 if (BE (mbclen == mbcdlen, 1))
322 memcpy (pstr->mbs + byte_idx, buf, mbclen); 324 memcpy (pstr->mbs + byte_idx, buf, mbclen);
323 else 325 else
324 { 326 {
@@ -339,11 +341,10 @@ build_wcs_upper_buffer (re_string_t *pstr)
339 { 341 {
340 /* It is an invalid character, an incomplete character 342 /* It is an invalid character, an incomplete character
341 at the end of the string, or '\0'. Just use the byte. */ 343 at the end of the string, or '\0'. Just use the byte. */
342 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
343 pstr->mbs[byte_idx] = ch; 344 pstr->mbs[byte_idx] = ch;
344 /* And also cast it to wide char. */ 345 /* And also cast it to wide char. */
345 pstr->wcs[byte_idx++] = (wchar_t) ch; 346 pstr->wcs[byte_idx++] = (wchar_t) ch;
346 if (BE (mbclen == (size_t) -1, 0)) 347 if (__glibc_unlikely (mbclen == (size_t) -1))
347 pstr->cur_state = prev_st; 348 pstr->cur_state = prev_st;
348 } 349 }
349 else 350 else
@@ -365,7 +366,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
365 offsets_needed: 366 offsets_needed:
366 remain_len = end_idx - byte_idx; 367 remain_len = end_idx - byte_idx;
367 prev_st = pstr->cur_state; 368 prev_st = pstr->cur_state;
368 if (BE (pstr->trans != NULL, 0)) 369 if (__glibc_unlikely (pstr->trans != NULL))
369 { 370 {
370 int i, ch; 371 int i, ch;
371 372
@@ -379,16 +380,15 @@ build_wcs_upper_buffer (re_string_t *pstr)
379 else 380 else
380 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; 381 p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
381 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); 382 mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
382 if (BE (mbclen < (size_t) -2, 1)) 383 if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
383 { 384 {
384 wchar_t wcu = wc; 385 wchar_t wcu = __towupper (wc);
385 if (iswlower (wc)) 386 if (wcu != wc)
386 { 387 {
387 size_t mbcdlen; 388 size_t mbcdlen;
388 389
389 wcu = towupper (wc); 390 mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st);
390 mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); 391 if (__glibc_likely (mbclen == mbcdlen))
391 if (BE (mbclen == mbcdlen, 1))
392 memcpy (pstr->mbs + byte_idx, buf, mbclen); 392 memcpy (pstr->mbs + byte_idx, buf, mbclen);
393 else if (mbcdlen != (size_t) -1) 393 else if (mbcdlen != (size_t) -1)
394 { 394 {
@@ -438,7 +438,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
438 else 438 else
439 memcpy (pstr->mbs + byte_idx, p, mbclen); 439 memcpy (pstr->mbs + byte_idx, p, mbclen);
440 440
441 if (BE (pstr->offsets_needed != 0, 0)) 441 if (__glibc_unlikely (pstr->offsets_needed != 0))
442 { 442 {
443 size_t i; 443 size_t i;
444 for (i = 0; i < mbclen; ++i) 444 for (i = 0; i < mbclen; ++i)
@@ -457,17 +457,17 @@ build_wcs_upper_buffer (re_string_t *pstr)
457 /* It is an invalid character or '\0'. Just use the byte. */ 457 /* It is an invalid character or '\0'. Just use the byte. */
458 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; 458 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
459 459
460 if (BE (pstr->trans != NULL, 0)) 460 if (__glibc_unlikely (pstr->trans != NULL))
461 ch = pstr->trans [ch]; 461 ch = pstr->trans [ch];
462 pstr->mbs[byte_idx] = ch; 462 pstr->mbs[byte_idx] = ch;
463 463
464 if (BE (pstr->offsets_needed != 0, 0)) 464 if (__glibc_unlikely (pstr->offsets_needed != 0))
465 pstr->offsets[byte_idx] = src_idx; 465 pstr->offsets[byte_idx] = src_idx;
466 ++src_idx; 466 ++src_idx;
467 467
468 /* And also cast it to wide char. */ 468 /* And also cast it to wide char. */
469 pstr->wcs[byte_idx++] = (wchar_t) ch; 469 pstr->wcs[byte_idx++] = (wchar_t) ch;
470 if (BE (mbclen == (size_t) -1, 0)) 470 if (__glibc_unlikely (mbclen == (size_t) -1))
471 pstr->cur_state = prev_st; 471 pstr->cur_state = prev_st;
472 } 472 }
473 else 473 else
@@ -486,7 +486,6 @@ build_wcs_upper_buffer (re_string_t *pstr)
486 Return the index. */ 486 Return the index. */
487 487
488static Idx 488static Idx
489internal_function
490re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) 489re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
491{ 490{
492 mbstate_t prev_st; 491 mbstate_t prev_st;
@@ -503,7 +502,8 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
503 prev_st = pstr->cur_state; 502 prev_st = pstr->cur_state;
504 mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, 503 mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
505 remain_len, &pstr->cur_state); 504 remain_len, &pstr->cur_state);
506 if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) 505 if (__glibc_unlikely (mbclen == (size_t) -2 || mbclen == (size_t) -1
506 || mbclen == 0))
507 { 507 {
508 /* We treat these cases as a single byte character. */ 508 /* We treat these cases as a single byte character. */
509 if (mbclen == 0 || remain_len == 0) 509 if (mbclen == 0 || remain_len == 0)
@@ -521,13 +521,11 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
521 *last_wc = wc; 521 *last_wc = wc;
522 return rawbuf_idx; 522 return rawbuf_idx;
523} 523}
524#endif /* RE_ENABLE_I18N */
525 524
526/* Build the buffer PSTR->MBS, and apply the translation if we need. 525/* Build the buffer PSTR->MBS, and apply the translation if we need.
527 This function is used in case of REG_ICASE. */ 526 This function is used in case of REG_ICASE. */
528 527
529static void 528static void
530internal_function
531build_upper_buffer (re_string_t *pstr) 529build_upper_buffer (re_string_t *pstr)
532{ 530{
533 Idx char_idx, end_idx; 531 Idx char_idx, end_idx;
@@ -536,12 +534,9 @@ build_upper_buffer (re_string_t *pstr)
536 for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) 534 for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
537 { 535 {
538 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; 536 int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
539 if (BE (pstr->trans != NULL, 0)) 537 if (__glibc_unlikely (pstr->trans != NULL))
540 ch = pstr->trans[ch]; 538 ch = pstr->trans[ch];
541 if (islower (ch)) 539 pstr->mbs[char_idx] = toupper (ch);
542 pstr->mbs[char_idx] = toupper (ch);
543 else
544 pstr->mbs[char_idx] = ch;
545 } 540 }
546 pstr->valid_len = char_idx; 541 pstr->valid_len = char_idx;
547 pstr->valid_raw_len = char_idx; 542 pstr->valid_raw_len = char_idx;
@@ -550,7 +545,6 @@ build_upper_buffer (re_string_t *pstr)
550/* Apply TRANS to the buffer in PSTR. */ 545/* Apply TRANS to the buffer in PSTR. */
551 546
552static void 547static void
553internal_function
554re_string_translate_buffer (re_string_t *pstr) 548re_string_translate_buffer (re_string_t *pstr)
555{ 549{
556 Idx buf_idx, end_idx; 550 Idx buf_idx, end_idx;
@@ -571,20 +565,18 @@ re_string_translate_buffer (re_string_t *pstr)
571 convert to upper case in case of REG_ICASE, apply translation. */ 565 convert to upper case in case of REG_ICASE, apply translation. */
572 566
573static reg_errcode_t 567static reg_errcode_t
574internal_function __attribute_warn_unused_result__ 568__attribute_warn_unused_result__
575re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) 569re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
576{ 570{
577 Idx offset; 571 Idx offset;
578 572
579 if (BE (pstr->raw_mbs_idx <= idx, 0)) 573 if (__glibc_unlikely (pstr->raw_mbs_idx <= idx))
580 offset = idx - pstr->raw_mbs_idx; 574 offset = idx - pstr->raw_mbs_idx;
581 else 575 else
582 { 576 {
583 /* Reset buffer. */ 577 /* Reset buffer. */
584#ifdef RE_ENABLE_I18N
585 if (pstr->mb_cur_max > 1) 578 if (pstr->mb_cur_max > 1)
586 memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); 579 memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
587#endif /* RE_ENABLE_I18N */
588 pstr->len = pstr->raw_len; 580 pstr->len = pstr->raw_len;
589 pstr->stop = pstr->raw_stop; 581 pstr->stop = pstr->raw_stop;
590 pstr->valid_len = 0; 582 pstr->valid_len = 0;
@@ -598,14 +590,13 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
598 offset = idx; 590 offset = idx;
599 } 591 }
600 592
601 if (BE (offset != 0, 1)) 593 if (__glibc_likely (offset != 0))
602 { 594 {
603 /* Should the already checked characters be kept? */ 595 /* Should the already checked characters be kept? */
604 if (BE (offset < pstr->valid_raw_len, 1)) 596 if (__glibc_likely (offset < pstr->valid_raw_len))
605 { 597 {
606 /* Yes, move them to the front of the buffer. */ 598 /* Yes, move them to the front of the buffer. */
607#ifdef RE_ENABLE_I18N 599 if (__glibc_unlikely (pstr->offsets_needed))
608 if (BE (pstr->offsets_needed, 0))
609 { 600 {
610 Idx low = 0, high = pstr->valid_len, mid; 601 Idx low = 0, high = pstr->valid_len, mid;
611 do 602 do
@@ -668,40 +659,32 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
668 } 659 }
669 } 660 }
670 else 661 else
671#endif
672 { 662 {
673 pstr->tip_context = re_string_context_at (pstr, offset - 1, 663 pstr->tip_context = re_string_context_at (pstr, offset - 1,
674 eflags); 664 eflags);
675#ifdef RE_ENABLE_I18N
676 if (pstr->mb_cur_max > 1) 665 if (pstr->mb_cur_max > 1)
677 memmove (pstr->wcs, pstr->wcs + offset, 666 memmove (pstr->wcs, pstr->wcs + offset,
678 (pstr->valid_len - offset) * sizeof (wint_t)); 667 (pstr->valid_len - offset) * sizeof (wint_t));
679#endif /* RE_ENABLE_I18N */ 668 if (__glibc_unlikely (pstr->mbs_allocated))
680 if (BE (pstr->mbs_allocated, 0))
681 memmove (pstr->mbs, pstr->mbs + offset, 669 memmove (pstr->mbs, pstr->mbs + offset,
682 pstr->valid_len - offset); 670 pstr->valid_len - offset);
683 pstr->valid_len -= offset; 671 pstr->valid_len -= offset;
684 pstr->valid_raw_len -= offset; 672 pstr->valid_raw_len -= offset;
685#if DEBUG 673 DEBUG_ASSERT (pstr->valid_len > 0);
686 assert (pstr->valid_len > 0);
687#endif
688 } 674 }
689 } 675 }
690 else 676 else
691 { 677 {
692#ifdef RE_ENABLE_I18N
693 /* No, skip all characters until IDX. */ 678 /* No, skip all characters until IDX. */
694 Idx prev_valid_len = pstr->valid_len; 679 Idx prev_valid_len = pstr->valid_len;
695 680
696 if (BE (pstr->offsets_needed, 0)) 681 if (__glibc_unlikely (pstr->offsets_needed))
697 { 682 {
698 pstr->len = pstr->raw_len - idx + offset; 683 pstr->len = pstr->raw_len - idx + offset;
699 pstr->stop = pstr->raw_stop - idx + offset; 684 pstr->stop = pstr->raw_stop - idx + offset;
700 pstr->offsets_needed = 0; 685 pstr->offsets_needed = 0;
701 } 686 }
702#endif
703 pstr->valid_len = 0; 687 pstr->valid_len = 0;
704#ifdef RE_ENABLE_I18N
705 if (pstr->mb_cur_max > 1) 688 if (pstr->mb_cur_max > 1)
706 { 689 {
707 Idx wcs_idx; 690 Idx wcs_idx;
@@ -721,7 +704,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
721#ifdef _LIBC 704#ifdef _LIBC
722 /* We know the wchar_t encoding is UCS4, so for the simple 705 /* We know the wchar_t encoding is UCS4, so for the simple
723 case, ASCII characters, skip the conversion step. */ 706 case, ASCII characters, skip the conversion step. */
724 if (isascii (*p) && BE (pstr->trans == NULL, 1)) 707 if (isascii (*p) && __glibc_likely (pstr->trans == NULL))
725 { 708 {
726 memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); 709 memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
727 /* pstr->valid_len = 0; */ 710 /* pstr->valid_len = 0; */
@@ -739,7 +722,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
739 size_t mbclen; 722 size_t mbclen;
740 723
741 const unsigned char *pp = p; 724 const unsigned char *pp = p;
742 if (BE (pstr->trans != NULL, 0)) 725 if (__glibc_unlikely (pstr->trans != NULL))
743 { 726 {
744 int i = mlen < 6 ? mlen : 6; 727 int i = mlen < 6 ? mlen : 6;
745 while (--i >= 0) 728 while (--i >= 0)
@@ -769,13 +752,13 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
769 pstr->tip_context 752 pstr->tip_context
770 = re_string_context_at (pstr, prev_valid_len - 1, eflags); 753 = re_string_context_at (pstr, prev_valid_len - 1, eflags);
771 else 754 else
772 pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) 755 pstr->tip_context = ((__glibc_unlikely (pstr->word_ops_used != 0)
773 && IS_WIDE_WORD_CHAR (wc)) 756 && IS_WIDE_WORD_CHAR (wc))
774 ? CONTEXT_WORD 757 ? CONTEXT_WORD
775 : ((IS_WIDE_NEWLINE (wc) 758 : ((IS_WIDE_NEWLINE (wc)
776 && pstr->newline_anchor) 759 && pstr->newline_anchor)
777 ? CONTEXT_NEWLINE : 0)); 760 ? CONTEXT_NEWLINE : 0));
778 if (BE (pstr->valid_len, 0)) 761 if (__glibc_unlikely (pstr->valid_len))
779 { 762 {
780 for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) 763 for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
781 pstr->wcs[wcs_idx] = WEOF; 764 pstr->wcs[wcs_idx] = WEOF;
@@ -785,7 +768,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
785 pstr->valid_raw_len = pstr->valid_len; 768 pstr->valid_raw_len = pstr->valid_len;
786 } 769 }
787 else 770 else
788#endif /* RE_ENABLE_I18N */
789 { 771 {
790 int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; 772 int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
791 pstr->valid_raw_len = 0; 773 pstr->valid_raw_len = 0;
@@ -797,7 +779,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
797 ? CONTEXT_NEWLINE : 0)); 779 ? CONTEXT_NEWLINE : 0));
798 } 780 }
799 } 781 }
800 if (!BE (pstr->mbs_allocated, 0)) 782 if (!__glibc_unlikely (pstr->mbs_allocated))
801 pstr->mbs += offset; 783 pstr->mbs += offset;
802 } 784 }
803 pstr->raw_mbs_idx = idx; 785 pstr->raw_mbs_idx = idx;
@@ -805,21 +787,19 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
805 pstr->stop -= offset; 787 pstr->stop -= offset;
806 788
807 /* Then build the buffers. */ 789 /* Then build the buffers. */
808#ifdef RE_ENABLE_I18N
809 if (pstr->mb_cur_max > 1) 790 if (pstr->mb_cur_max > 1)
810 { 791 {
811 if (pstr->icase) 792 if (pstr->icase)
812 { 793 {
813 reg_errcode_t ret = build_wcs_upper_buffer (pstr); 794 reg_errcode_t ret = build_wcs_upper_buffer (pstr);
814 if (BE (ret != REG_NOERROR, 0)) 795 if (__glibc_unlikely (ret != REG_NOERROR))
815 return ret; 796 return ret;
816 } 797 }
817 else 798 else
818 build_wcs_buffer (pstr); 799 build_wcs_buffer (pstr);
819 } 800 }
820 else 801 else
821#endif /* RE_ENABLE_I18N */ 802 if (__glibc_unlikely (pstr->mbs_allocated))
822 if (BE (pstr->mbs_allocated, 0))
823 { 803 {
824 if (pstr->icase) 804 if (pstr->icase)
825 build_upper_buffer (pstr); 805 build_upper_buffer (pstr);
@@ -834,50 +814,42 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
834} 814}
835 815
836static unsigned char 816static unsigned char
837internal_function __attribute__ ((pure)) 817__attribute__ ((pure))
838re_string_peek_byte_case (const re_string_t *pstr, Idx idx) 818re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
839{ 819{
840 int ch; 820 int ch;
841 Idx off; 821 Idx off;
842 822
843 /* Handle the common (easiest) cases first. */ 823 /* Handle the common (easiest) cases first. */
844 if (BE (!pstr->mbs_allocated, 1)) 824 if (__glibc_likely (!pstr->mbs_allocated))
845 return re_string_peek_byte (pstr, idx); 825 return re_string_peek_byte (pstr, idx);
846 826
847#ifdef RE_ENABLE_I18N
848 if (pstr->mb_cur_max > 1 827 if (pstr->mb_cur_max > 1
849 && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) 828 && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
850 return re_string_peek_byte (pstr, idx); 829 return re_string_peek_byte (pstr, idx);
851#endif
852 830
853 off = pstr->cur_idx + idx; 831 off = pstr->cur_idx + idx;
854#ifdef RE_ENABLE_I18N
855 if (pstr->offsets_needed) 832 if (pstr->offsets_needed)
856 off = pstr->offsets[off]; 833 off = pstr->offsets[off];
857#endif
858 834
859 ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; 835 ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
860 836
861#ifdef RE_ENABLE_I18N
862 /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I 837 /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
863 this function returns CAPITAL LETTER I instead of first byte of 838 this function returns CAPITAL LETTER I instead of first byte of
864 DOTLESS SMALL LETTER I. The latter would confuse the parser, 839 DOTLESS SMALL LETTER I. The latter would confuse the parser,
865 since peek_byte_case doesn't advance cur_idx in any way. */ 840 since peek_byte_case doesn't advance cur_idx in any way. */
866 if (pstr->offsets_needed && !isascii (ch)) 841 if (pstr->offsets_needed && !isascii (ch))
867 return re_string_peek_byte (pstr, idx); 842 return re_string_peek_byte (pstr, idx);
868#endif
869 843
870 return ch; 844 return ch;
871} 845}
872 846
873static unsigned char 847static unsigned char
874internal_function
875re_string_fetch_byte_case (re_string_t *pstr) 848re_string_fetch_byte_case (re_string_t *pstr)
876{ 849{
877 if (BE (!pstr->mbs_allocated, 1)) 850 if (__glibc_likely (!pstr->mbs_allocated))
878 return re_string_fetch_byte (pstr); 851 return re_string_fetch_byte (pstr);
879 852
880#ifdef RE_ENABLE_I18N
881 if (pstr->offsets_needed) 853 if (pstr->offsets_needed)
882 { 854 {
883 Idx off; 855 Idx off;
@@ -903,19 +875,15 @@ re_string_fetch_byte_case (re_string_t *pstr)
903 re_string_char_size_at (pstr, pstr->cur_idx)); 875 re_string_char_size_at (pstr, pstr->cur_idx));
904 return ch; 876 return ch;
905 } 877 }
906#endif
907 878
908 return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; 879 return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
909} 880}
910 881
911static void 882static void
912internal_function
913re_string_destruct (re_string_t *pstr) 883re_string_destruct (re_string_t *pstr)
914{ 884{
915#ifdef RE_ENABLE_I18N
916 re_free (pstr->wcs); 885 re_free (pstr->wcs);
917 re_free (pstr->offsets); 886 re_free (pstr->offsets);
918#endif /* RE_ENABLE_I18N */
919 if (pstr->mbs_allocated) 887 if (pstr->mbs_allocated)
920 re_free (pstr->mbs); 888 re_free (pstr->mbs);
921} 889}
@@ -923,40 +891,35 @@ re_string_destruct (re_string_t *pstr)
923/* Return the context at IDX in INPUT. */ 891/* Return the context at IDX in INPUT. */
924 892
925static unsigned int 893static unsigned int
926internal_function
927re_string_context_at (const re_string_t *input, Idx idx, int eflags) 894re_string_context_at (const re_string_t *input, Idx idx, int eflags)
928{ 895{
929 int c; 896 int c;
930 if (BE (! REG_VALID_INDEX (idx), 0)) 897 if (__glibc_unlikely (idx < 0))
931 /* In this case, we use the value stored in input->tip_context, 898 /* In this case, we use the value stored in input->tip_context,
932 since we can't know the character in input->mbs[-1] here. */ 899 since we can't know the character in input->mbs[-1] here. */
933 return input->tip_context; 900 return input->tip_context;
934 if (BE (idx == input->len, 0)) 901 if (__glibc_unlikely (idx == input->len))
935 return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF 902 return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
936 : CONTEXT_NEWLINE | CONTEXT_ENDBUF); 903 : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
937#ifdef RE_ENABLE_I18N
938 if (input->mb_cur_max > 1) 904 if (input->mb_cur_max > 1)
939 { 905 {
940 wint_t wc; 906 wint_t wc;
941 Idx wc_idx = idx; 907 Idx wc_idx = idx;
942 while(input->wcs[wc_idx] == WEOF) 908 while(input->wcs[wc_idx] == WEOF)
943 { 909 {
944#ifdef DEBUG 910 DEBUG_ASSERT (wc_idx >= 0);
945 /* It must not happen. */
946 assert (REG_VALID_INDEX (wc_idx));
947#endif
948 --wc_idx; 911 --wc_idx;
949 if (! REG_VALID_INDEX (wc_idx)) 912 if (wc_idx < 0)
950 return input->tip_context; 913 return input->tip_context;
951 } 914 }
952 wc = input->wcs[wc_idx]; 915 wc = input->wcs[wc_idx];
953 if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) 916 if (__glibc_unlikely (input->word_ops_used != 0)
917 && IS_WIDE_WORD_CHAR (wc))
954 return CONTEXT_WORD; 918 return CONTEXT_WORD;
955 return (IS_WIDE_NEWLINE (wc) && input->newline_anchor 919 return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
956 ? CONTEXT_NEWLINE : 0); 920 ? CONTEXT_NEWLINE : 0);
957 } 921 }
958 else 922 else
959#endif
960 { 923 {
961 c = re_string_byte_at (input, idx); 924 c = re_string_byte_at (input, idx);
962 if (bitset_contain (input->word_char, c)) 925 if (bitset_contain (input->word_char, c))
@@ -968,25 +931,26 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags)
968/* Functions for set operation. */ 931/* Functions for set operation. */
969 932
970static reg_errcode_t 933static reg_errcode_t
971internal_function __attribute_warn_unused_result__ 934__attribute_warn_unused_result__
972re_node_set_alloc (re_node_set *set, Idx size) 935re_node_set_alloc (re_node_set *set, Idx size)
973{ 936{
974 set->alloc = size; 937 set->alloc = size;
975 set->nelem = 0; 938 set->nelem = 0;
976 set->elems = re_malloc (Idx, size); 939 set->elems = re_malloc (Idx, size);
977 if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0)) 940 if (__glibc_unlikely (set->elems == NULL)
941 && (MALLOC_0_IS_NONNULL || size != 0))
978 return REG_ESPACE; 942 return REG_ESPACE;
979 return REG_NOERROR; 943 return REG_NOERROR;
980} 944}
981 945
982static reg_errcode_t 946static reg_errcode_t
983internal_function __attribute_warn_unused_result__ 947__attribute_warn_unused_result__
984re_node_set_init_1 (re_node_set *set, Idx elem) 948re_node_set_init_1 (re_node_set *set, Idx elem)
985{ 949{
986 set->alloc = 1; 950 set->alloc = 1;
987 set->nelem = 1; 951 set->nelem = 1;
988 set->elems = re_malloc (Idx, 1); 952 set->elems = re_malloc (Idx, 1);
989 if (BE (set->elems == NULL, 0)) 953 if (__glibc_unlikely (set->elems == NULL))
990 { 954 {
991 set->alloc = set->nelem = 0; 955 set->alloc = set->nelem = 0;
992 return REG_ESPACE; 956 return REG_ESPACE;
@@ -996,12 +960,12 @@ re_node_set_init_1 (re_node_set *set, Idx elem)
996} 960}
997 961
998static reg_errcode_t 962static reg_errcode_t
999internal_function __attribute_warn_unused_result__ 963__attribute_warn_unused_result__
1000re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) 964re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
1001{ 965{
1002 set->alloc = 2; 966 set->alloc = 2;
1003 set->elems = re_malloc (Idx, 2); 967 set->elems = re_malloc (Idx, 2);
1004 if (BE (set->elems == NULL, 0)) 968 if (__glibc_unlikely (set->elems == NULL))
1005 return REG_ESPACE; 969 return REG_ESPACE;
1006 if (elem1 == elem2) 970 if (elem1 == elem2)
1007 { 971 {
@@ -1026,7 +990,7 @@ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
1026} 990}
1027 991
1028static reg_errcode_t 992static reg_errcode_t
1029internal_function __attribute_warn_unused_result__ 993__attribute_warn_unused_result__
1030re_node_set_init_copy (re_node_set *dest, const re_node_set *src) 994re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
1031{ 995{
1032 dest->nelem = src->nelem; 996 dest->nelem = src->nelem;
@@ -1034,7 +998,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
1034 { 998 {
1035 dest->alloc = dest->nelem; 999 dest->alloc = dest->nelem;
1036 dest->elems = re_malloc (Idx, dest->alloc); 1000 dest->elems = re_malloc (Idx, dest->alloc);
1037 if (BE (dest->elems == NULL, 0)) 1001 if (__glibc_unlikely (dest->elems == NULL))
1038 { 1002 {
1039 dest->alloc = dest->nelem = 0; 1003 dest->alloc = dest->nelem = 0;
1040 return REG_ESPACE; 1004 return REG_ESPACE;
@@ -1051,7 +1015,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
1051 Note: We assume dest->elems is NULL, when dest->alloc is 0. */ 1015 Note: We assume dest->elems is NULL, when dest->alloc is 0. */
1052 1016
1053static reg_errcode_t 1017static reg_errcode_t
1054internal_function __attribute_warn_unused_result__ 1018__attribute_warn_unused_result__
1055re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, 1019re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1056 const re_node_set *src2) 1020 const re_node_set *src2)
1057{ 1021{
@@ -1065,7 +1029,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1065 { 1029 {
1066 Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; 1030 Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
1067 Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); 1031 Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
1068 if (BE (new_elems == NULL, 0)) 1032 if (__glibc_unlikely (new_elems == NULL))
1069 return REG_ESPACE; 1033 return REG_ESPACE;
1070 dest->elems = new_elems; 1034 dest->elems = new_elems;
1071 dest->alloc = new_alloc; 1035 dest->alloc = new_alloc;
@@ -1082,25 +1046,25 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1082 if (src1->elems[i1] == src2->elems[i2]) 1046 if (src1->elems[i1] == src2->elems[i2])
1083 { 1047 {
1084 /* Try to find the item in DEST. Maybe we could binary search? */ 1048 /* Try to find the item in DEST. Maybe we could binary search? */
1085 while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) 1049 while (id >= 0 && dest->elems[id] > src1->elems[i1])
1086 --id; 1050 --id;
1087 1051
1088 if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) 1052 if (id < 0 || dest->elems[id] != src1->elems[i1])
1089 dest->elems[--sbase] = src1->elems[i1]; 1053 dest->elems[--sbase] = src1->elems[i1];
1090 1054
1091 if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) 1055 if (--i1 < 0 || --i2 < 0)
1092 break; 1056 break;
1093 } 1057 }
1094 1058
1095 /* Lower the highest of the two items. */ 1059 /* Lower the highest of the two items. */
1096 else if (src1->elems[i1] < src2->elems[i2]) 1060 else if (src1->elems[i1] < src2->elems[i2])
1097 { 1061 {
1098 if (! REG_VALID_INDEX (--i2)) 1062 if (--i2 < 0)
1099 break; 1063 break;
1100 } 1064 }
1101 else 1065 else
1102 { 1066 {
1103 if (! REG_VALID_INDEX (--i1)) 1067 if (--i1 < 0)
1104 break; 1068 break;
1105 } 1069 }
1106 } 1070 }
@@ -1113,7 +1077,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1113 DEST elements are already in place; this is more or 1077 DEST elements are already in place; this is more or
1114 less the same loop that is in re_node_set_merge. */ 1078 less the same loop that is in re_node_set_merge. */
1115 dest->nelem += delta; 1079 dest->nelem += delta;
1116 if (delta > 0 && REG_VALID_INDEX (id)) 1080 if (delta > 0 && id >= 0)
1117 for (;;) 1081 for (;;)
1118 { 1082 {
1119 if (dest->elems[is] > dest->elems[id]) 1083 if (dest->elems[is] > dest->elems[id])
@@ -1127,7 +1091,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1127 { 1091 {
1128 /* Slide from the bottom. */ 1092 /* Slide from the bottom. */
1129 dest->elems[id + delta] = dest->elems[id]; 1093 dest->elems[id + delta] = dest->elems[id];
1130 if (! REG_VALID_INDEX (--id)) 1094 if (--id < 0)
1131 break; 1095 break;
1132 } 1096 }
1133 } 1097 }
@@ -1142,7 +1106,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
1142 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ 1106 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
1143 1107
1144static reg_errcode_t 1108static reg_errcode_t
1145internal_function __attribute_warn_unused_result__ 1109__attribute_warn_unused_result__
1146re_node_set_init_union (re_node_set *dest, const re_node_set *src1, 1110re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1147 const re_node_set *src2) 1111 const re_node_set *src2)
1148{ 1112{
@@ -1151,7 +1115,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1151 { 1115 {
1152 dest->alloc = src1->nelem + src2->nelem; 1116 dest->alloc = src1->nelem + src2->nelem;
1153 dest->elems = re_malloc (Idx, dest->alloc); 1117 dest->elems = re_malloc (Idx, dest->alloc);
1154 if (BE (dest->elems == NULL, 0)) 1118 if (__glibc_unlikely (dest->elems == NULL))
1155 return REG_ESPACE; 1119 return REG_ESPACE;
1156 } 1120 }
1157 else 1121 else
@@ -1195,7 +1159,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1195 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ 1159 DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
1196 1160
1197static reg_errcode_t 1161static reg_errcode_t
1198internal_function __attribute_warn_unused_result__ 1162__attribute_warn_unused_result__
1199re_node_set_merge (re_node_set *dest, const re_node_set *src) 1163re_node_set_merge (re_node_set *dest, const re_node_set *src)
1200{ 1164{
1201 Idx is, id, sbase, delta; 1165 Idx is, id, sbase, delta;
@@ -1205,14 +1169,18 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1205 { 1169 {
1206 Idx new_alloc = 2 * (src->nelem + dest->alloc); 1170 Idx new_alloc = 2 * (src->nelem + dest->alloc);
1207 Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); 1171 Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
1208 if (BE (new_buffer == NULL, 0)) 1172 if (__glibc_unlikely (new_buffer == NULL))
1209 return REG_ESPACE; 1173 return REG_ESPACE;
1210 dest->elems = new_buffer; 1174 dest->elems = new_buffer;
1211 dest->alloc = new_alloc; 1175 dest->alloc = new_alloc;
1212 } 1176 }
1213 1177
1214 if (BE (dest->nelem == 0, 0)) 1178 if (__glibc_unlikely (dest->nelem == 0))
1215 { 1179 {
1180 /* Although we already guaranteed above that dest->alloc != 0 and
1181 therefore dest->elems != NULL, add a debug assertion to pacify
1182 GCC 11.2.1's -fanalyzer. */
1183 DEBUG_ASSERT (dest->elems);
1216 dest->nelem = src->nelem; 1184 dest->nelem = src->nelem;
1217 memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); 1185 memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
1218 return REG_NOERROR; 1186 return REG_NOERROR;
@@ -1221,8 +1189,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1221 /* Copy into the top of DEST the items of SRC that are not 1189 /* Copy into the top of DEST the items of SRC that are not
1222 found in DEST. Maybe we could binary search in DEST? */ 1190 found in DEST. Maybe we could binary search in DEST? */
1223 for (sbase = dest->nelem + 2 * src->nelem, 1191 for (sbase = dest->nelem + 2 * src->nelem,
1224 is = src->nelem - 1, id = dest->nelem - 1; 1192 is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )
1225 REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
1226 { 1193 {
1227 if (dest->elems[id] == src->elems[is]) 1194 if (dest->elems[id] == src->elems[is])
1228 is--, id--; 1195 is--, id--;
@@ -1232,7 +1199,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1232 --id; 1199 --id;
1233 } 1200 }
1234 1201
1235 if (REG_VALID_INDEX (is)) 1202 if (is >= 0)
1236 { 1203 {
1237 /* If DEST is exhausted, the remaining items of SRC must be unique. */ 1204 /* If DEST is exhausted, the remaining items of SRC must be unique. */
1238 sbase -= is + 1; 1205 sbase -= is + 1;
@@ -1261,7 +1228,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1261 { 1228 {
1262 /* Slide from the bottom. */ 1229 /* Slide from the bottom. */
1263 dest->elems[id + delta] = dest->elems[id]; 1230 dest->elems[id + delta] = dest->elems[id];
1264 if (! REG_VALID_INDEX (--id)) 1231 if (--id < 0)
1265 { 1232 {
1266 /* Copy remaining SRC elements. */ 1233 /* Copy remaining SRC elements. */
1267 memcpy (dest->elems, dest->elems + sbase, 1234 memcpy (dest->elems, dest->elems + sbase,
@@ -1279,17 +1246,20 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
1279 Return true if successful. */ 1246 Return true if successful. */
1280 1247
1281static bool 1248static bool
1282internal_function __attribute_warn_unused_result__ 1249__attribute_warn_unused_result__
1283re_node_set_insert (re_node_set *set, Idx elem) 1250re_node_set_insert (re_node_set *set, Idx elem)
1284{ 1251{
1285 Idx idx; 1252 Idx idx;
1286 /* In case the set is empty. */ 1253 /* In case the set is empty. */
1287 if (set->alloc == 0) 1254 if (set->alloc == 0)
1288 return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); 1255 return __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR);
1289 1256
1290 if (BE (set->nelem, 0) == 0) 1257 if (__glibc_unlikely (set->nelem) == 0)
1291 { 1258 {
1292 /* We already guaranteed above that set->alloc != 0. */ 1259 /* Although we already guaranteed above that set->alloc != 0 and
1260 therefore set->elems != NULL, add a debug assertion to pacify
1261 GCC 11.2 -fanalyzer. */
1262 DEBUG_ASSERT (set->elems);
1293 set->elems[0] = elem; 1263 set->elems[0] = elem;
1294 ++set->nelem; 1264 ++set->nelem;
1295 return true; 1265 return true;
@@ -1301,7 +1271,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
1301 Idx *new_elems; 1271 Idx *new_elems;
1302 set->alloc = set->alloc * 2; 1272 set->alloc = set->alloc * 2;
1303 new_elems = re_realloc (set->elems, Idx, set->alloc); 1273 new_elems = re_realloc (set->elems, Idx, set->alloc);
1304 if (BE (new_elems == NULL, 0)) 1274 if (__glibc_unlikely (new_elems == NULL))
1305 return false; 1275 return false;
1306 set->elems = new_elems; 1276 set->elems = new_elems;
1307 } 1277 }
@@ -1310,7 +1280,6 @@ re_node_set_insert (re_node_set *set, Idx elem)
1310 first element separately to skip a check in the inner loop. */ 1280 first element separately to skip a check in the inner loop. */
1311 if (elem < set->elems[0]) 1281 if (elem < set->elems[0])
1312 { 1282 {
1313 idx = 0;
1314 for (idx = set->nelem; idx > 0; idx--) 1283 for (idx = set->nelem; idx > 0; idx--)
1315 set->elems[idx] = set->elems[idx - 1]; 1284 set->elems[idx] = set->elems[idx - 1];
1316 } 1285 }
@@ -1318,6 +1287,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
1318 { 1287 {
1319 for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) 1288 for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
1320 set->elems[idx] = set->elems[idx - 1]; 1289 set->elems[idx] = set->elems[idx - 1];
1290 DEBUG_ASSERT (set->elems[idx - 1] < elem);
1321 } 1291 }
1322 1292
1323 /* Insert the new element. */ 1293 /* Insert the new element. */
@@ -1331,7 +1301,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
1331 Return true if successful. */ 1301 Return true if successful. */
1332 1302
1333static bool 1303static bool
1334internal_function __attribute_warn_unused_result__ 1304__attribute_warn_unused_result__
1335re_node_set_insert_last (re_node_set *set, Idx elem) 1305re_node_set_insert_last (re_node_set *set, Idx elem)
1336{ 1306{
1337 /* Realloc if we need. */ 1307 /* Realloc if we need. */
@@ -1340,7 +1310,7 @@ re_node_set_insert_last (re_node_set *set, Idx elem)
1340 Idx *new_elems; 1310 Idx *new_elems;
1341 set->alloc = (set->alloc + 1) * 2; 1311 set->alloc = (set->alloc + 1) * 2;
1342 new_elems = re_realloc (set->elems, Idx, set->alloc); 1312 new_elems = re_realloc (set->elems, Idx, set->alloc);
1343 if (BE (new_elems == NULL, 0)) 1313 if (__glibc_unlikely (new_elems == NULL))
1344 return false; 1314 return false;
1345 set->elems = new_elems; 1315 set->elems = new_elems;
1346 } 1316 }
@@ -1354,13 +1324,13 @@ re_node_set_insert_last (re_node_set *set, Idx elem)
1354 Return true if SET1 and SET2 are equivalent. */ 1324 Return true if SET1 and SET2 are equivalent. */
1355 1325
1356static bool 1326static bool
1357internal_function __attribute__ ((pure)) 1327__attribute__ ((pure))
1358re_node_set_compare (const re_node_set *set1, const re_node_set *set2) 1328re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
1359{ 1329{
1360 Idx i; 1330 Idx i;
1361 if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) 1331 if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
1362 return false; 1332 return false;
1363 for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) 1333 for (i = set1->nelem ; --i >= 0 ; )
1364 if (set1->elems[i] != set2->elems[i]) 1334 if (set1->elems[i] != set2->elems[i])
1365 return false; 1335 return false;
1366 return true; 1336 return true;
@@ -1369,11 +1339,11 @@ re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
1369/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ 1339/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */
1370 1340
1371static Idx 1341static Idx
1372internal_function __attribute__ ((pure)) 1342__attribute__ ((pure))
1373re_node_set_contains (const re_node_set *set, Idx elem) 1343re_node_set_contains (const re_node_set *set, Idx elem)
1374{ 1344{
1375 __re_size_t idx, right, mid; 1345 __re_size_t idx, right, mid;
1376 if (! REG_VALID_NONZERO_INDEX (set->nelem)) 1346 if (set->nelem <= 0)
1377 return 0; 1347 return 0;
1378 1348
1379 /* Binary search the element. */ 1349 /* Binary search the element. */
@@ -1391,7 +1361,6 @@ re_node_set_contains (const re_node_set *set, Idx elem)
1391} 1361}
1392 1362
1393static void 1363static void
1394internal_function
1395re_node_set_remove_at (re_node_set *set, Idx idx) 1364re_node_set_remove_at (re_node_set *set, Idx idx)
1396{ 1365{
1397 if (idx < 0 || idx >= set->nelem) 1366 if (idx < 0 || idx >= set->nelem)
@@ -1403,13 +1372,12 @@ re_node_set_remove_at (re_node_set *set, Idx idx)
1403 1372
1404 1373
1405/* Add the token TOKEN to dfa->nodes, and return the index of the token. 1374/* Add the token TOKEN to dfa->nodes, and return the index of the token.
1406 Or return REG_MISSING if an error occurred. */ 1375 Or return -1 if an error occurred. */
1407 1376
1408static Idx 1377static Idx
1409internal_function
1410re_dfa_add_node (re_dfa_t *dfa, re_token_t token) 1378re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
1411{ 1379{
1412 if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) 1380 if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc))
1413 { 1381 {
1414 size_t new_nodes_alloc = dfa->nodes_alloc * 2; 1382 size_t new_nodes_alloc = dfa->nodes_alloc * 2;
1415 Idx *new_nexts, *new_indices; 1383 Idx *new_nexts, *new_indices;
@@ -1420,41 +1388,43 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
1420 const size_t max_object_size = MAX (sizeof (re_token_t), 1388 const size_t max_object_size = MAX (sizeof (re_token_t),
1421 MAX (sizeof (re_node_set), 1389 MAX (sizeof (re_node_set),
1422 sizeof (Idx))); 1390 sizeof (Idx)));
1423 if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_nodes_alloc, 0)) 1391 if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
1424 return REG_MISSING; 1392 < new_nodes_alloc))
1393 return -1;
1425 1394
1426 new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); 1395 new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
1427 if (BE (new_nodes == NULL, 0)) 1396 if (__glibc_unlikely (new_nodes == NULL))
1428 return REG_MISSING; 1397 return -1;
1429 dfa->nodes = new_nodes; 1398 dfa->nodes = new_nodes;
1399 dfa->nodes_alloc = new_nodes_alloc;
1430 new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); 1400 new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
1401 if (new_nexts != NULL)
1402 dfa->nexts = new_nexts;
1431 new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); 1403 new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
1404 if (new_indices != NULL)
1405 dfa->org_indices = new_indices;
1432 new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); 1406 new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
1407 if (new_edests != NULL)
1408 dfa->edests = new_edests;
1433 new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); 1409 new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
1434 if (BE (new_nexts == NULL || new_indices == NULL 1410 if (new_eclosures != NULL)
1435 || new_edests == NULL || new_eclosures == NULL, 0)) 1411 dfa->eclosures = new_eclosures;
1436 return REG_MISSING; 1412 if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL
1437 dfa->nexts = new_nexts; 1413 || new_edests == NULL || new_eclosures == NULL))
1438 dfa->org_indices = new_indices; 1414 return -1;
1439 dfa->edests = new_edests;
1440 dfa->eclosures = new_eclosures;
1441 dfa->nodes_alloc = new_nodes_alloc;
1442 } 1415 }
1443 dfa->nodes[dfa->nodes_len] = token; 1416 dfa->nodes[dfa->nodes_len] = token;
1444 dfa->nodes[dfa->nodes_len].constraint = 0; 1417 dfa->nodes[dfa->nodes_len].constraint = 0;
1445#ifdef RE_ENABLE_I18N
1446 dfa->nodes[dfa->nodes_len].accept_mb = 1418 dfa->nodes[dfa->nodes_len].accept_mb =
1447 ((token.type == OP_PERIOD && dfa->mb_cur_max > 1) 1419 ((token.type == OP_PERIOD && dfa->mb_cur_max > 1)
1448 || token.type == COMPLEX_BRACKET); 1420 || token.type == COMPLEX_BRACKET);
1449#endif 1421 dfa->nexts[dfa->nodes_len] = -1;
1450 dfa->nexts[dfa->nodes_len] = REG_MISSING;
1451 re_node_set_init_empty (dfa->edests + dfa->nodes_len); 1422 re_node_set_init_empty (dfa->edests + dfa->nodes_len);
1452 re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); 1423 re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
1453 return dfa->nodes_len++; 1424 return dfa->nodes_len++;
1454} 1425}
1455 1426
1456static re_hashval_t 1427static re_hashval_t
1457internal_function
1458calc_state_hash (const re_node_set *nodes, unsigned int context) 1428calc_state_hash (const re_node_set *nodes, unsigned int context)
1459{ 1429{
1460 re_hashval_t hash = nodes->nelem + context; 1430 re_hashval_t hash = nodes->nelem + context;
@@ -1474,7 +1444,7 @@ calc_state_hash (const re_node_set *nodes, unsigned int context)
1474 optimization. */ 1444 optimization. */
1475 1445
1476static re_dfastate_t * 1446static re_dfastate_t *
1477internal_function __attribute_warn_unused_result__ 1447__attribute_warn_unused_result__
1478re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, 1448re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1479 const re_node_set *nodes) 1449 const re_node_set *nodes)
1480{ 1450{
@@ -1482,11 +1452,11 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1482 re_dfastate_t *new_state; 1452 re_dfastate_t *new_state;
1483 struct re_state_table_entry *spot; 1453 struct re_state_table_entry *spot;
1484 Idx i; 1454 Idx i;
1485#ifdef lint 1455#if defined GCC_LINT || defined lint
1486 /* Suppress bogus uninitialized-variable warnings. */ 1456 /* Suppress bogus uninitialized-variable warnings. */
1487 *err = REG_NOERROR; 1457 *err = REG_NOERROR;
1488#endif 1458#endif
1489 if (BE (nodes->nelem == 0, 0)) 1459 if (__glibc_unlikely (nodes->nelem == 0))
1490 { 1460 {
1491 *err = REG_NOERROR; 1461 *err = REG_NOERROR;
1492 return NULL; 1462 return NULL;
@@ -1505,7 +1475,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1505 1475
1506 /* There are no appropriate state in the dfa, create the new one. */ 1476 /* There are no appropriate state in the dfa, create the new one. */
1507 new_state = create_ci_newstate (dfa, nodes, hash); 1477 new_state = create_ci_newstate (dfa, nodes, hash);
1508 if (BE (new_state == NULL, 0)) 1478 if (__glibc_unlikely (new_state == NULL))
1509 *err = REG_ESPACE; 1479 *err = REG_ESPACE;
1510 1480
1511 return new_state; 1481 return new_state;
@@ -1522,7 +1492,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
1522 optimization. */ 1492 optimization. */
1523 1493
1524static re_dfastate_t * 1494static re_dfastate_t *
1525internal_function __attribute_warn_unused_result__ 1495__attribute_warn_unused_result__
1526re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, 1496re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
1527 const re_node_set *nodes, unsigned int context) 1497 const re_node_set *nodes, unsigned int context)
1528{ 1498{
@@ -1530,7 +1500,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
1530 re_dfastate_t *new_state; 1500 re_dfastate_t *new_state;
1531 struct re_state_table_entry *spot; 1501 struct re_state_table_entry *spot;
1532 Idx i; 1502 Idx i;
1533#ifdef lint 1503#if defined GCC_LINT || defined lint
1534 /* Suppress bogus uninitialized-variable warnings. */ 1504 /* Suppress bogus uninitialized-variable warnings. */
1535 *err = REG_NOERROR; 1505 *err = REG_NOERROR;
1536#endif 1506#endif
@@ -1552,7 +1522,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
1552 } 1522 }
1553 /* There are no appropriate state in 'dfa', create the new one. */ 1523 /* There are no appropriate state in 'dfa', create the new one. */
1554 new_state = create_cd_newstate (dfa, nodes, context, hash); 1524 new_state = create_cd_newstate (dfa, nodes, context, hash);
1555 if (BE (new_state == NULL, 0)) 1525 if (__glibc_unlikely (new_state == NULL))
1556 *err = REG_ESPACE; 1526 *err = REG_ESPACE;
1557 1527
1558 return new_state; 1528 return new_state;
@@ -1573,7 +1543,7 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
1573 1543
1574 newstate->hash = hash; 1544 newstate->hash = hash;
1575 err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); 1545 err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
1576 if (BE (err != REG_NOERROR, 0)) 1546 if (__glibc_unlikely (err != REG_NOERROR))
1577 return REG_ESPACE; 1547 return REG_ESPACE;
1578 for (i = 0; i < newstate->nodes.nelem; i++) 1548 for (i = 0; i < newstate->nodes.nelem; i++)
1579 { 1549 {
@@ -1584,12 +1554,12 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
1584 } 1554 }
1585 1555
1586 spot = dfa->state_table + (hash & dfa->state_hash_mask); 1556 spot = dfa->state_table + (hash & dfa->state_hash_mask);
1587 if (BE (spot->alloc <= spot->num, 0)) 1557 if (__glibc_unlikely (spot->alloc <= spot->num))
1588 { 1558 {
1589 Idx new_alloc = 2 * spot->num + 2; 1559 Idx new_alloc = 2 * spot->num + 2;
1590 re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, 1560 re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
1591 new_alloc); 1561 new_alloc);
1592 if (BE (new_array == NULL, 0)) 1562 if (__glibc_unlikely (new_array == NULL))
1593 return REG_ESPACE; 1563 return REG_ESPACE;
1594 spot->array = new_array; 1564 spot->array = new_array;
1595 spot->alloc = new_alloc; 1565 spot->alloc = new_alloc;
@@ -1618,7 +1588,7 @@ free_state (re_dfastate_t *state)
1618 Return the new state if succeeded, otherwise return NULL. */ 1588 Return the new state if succeeded, otherwise return NULL. */
1619 1589
1620static re_dfastate_t * 1590static re_dfastate_t *
1621internal_function __attribute_warn_unused_result__ 1591__attribute_warn_unused_result__
1622create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, 1592create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1623 re_hashval_t hash) 1593 re_hashval_t hash)
1624{ 1594{
@@ -1627,10 +1597,10 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1627 re_dfastate_t *newstate; 1597 re_dfastate_t *newstate;
1628 1598
1629 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); 1599 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
1630 if (BE (newstate == NULL, 0)) 1600 if (__glibc_unlikely (newstate == NULL))
1631 return NULL; 1601 return NULL;
1632 err = re_node_set_init_copy (&newstate->nodes, nodes); 1602 err = re_node_set_init_copy (&newstate->nodes, nodes);
1633 if (BE (err != REG_NOERROR, 0)) 1603 if (__glibc_unlikely (err != REG_NOERROR))
1634 { 1604 {
1635 re_free (newstate); 1605 re_free (newstate);
1636 return NULL; 1606 return NULL;
@@ -1643,9 +1613,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1643 re_token_type_t type = node->type; 1613 re_token_type_t type = node->type;
1644 if (type == CHARACTER && !node->constraint) 1614 if (type == CHARACTER && !node->constraint)
1645 continue; 1615 continue;
1646#ifdef RE_ENABLE_I18N
1647 newstate->accept_mb |= node->accept_mb; 1616 newstate->accept_mb |= node->accept_mb;
1648#endif /* RE_ENABLE_I18N */
1649 1617
1650 /* If the state has the halt node, the state is a halt state. */ 1618 /* If the state has the halt node, the state is a halt state. */
1651 if (type == END_OF_RE) 1619 if (type == END_OF_RE)
@@ -1656,7 +1624,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1656 newstate->has_constraint = 1; 1624 newstate->has_constraint = 1;
1657 } 1625 }
1658 err = register_state (dfa, newstate, hash); 1626 err = register_state (dfa, newstate, hash);
1659 if (BE (err != REG_NOERROR, 0)) 1627 if (__glibc_unlikely (err != REG_NOERROR))
1660 { 1628 {
1661 free_state (newstate); 1629 free_state (newstate);
1662 newstate = NULL; 1630 newstate = NULL;
@@ -1668,7 +1636,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1668 Return the new state if succeeded, otherwise return NULL. */ 1636 Return the new state if succeeded, otherwise return NULL. */
1669 1637
1670static re_dfastate_t * 1638static re_dfastate_t *
1671internal_function __attribute_warn_unused_result__ 1639__attribute_warn_unused_result__
1672create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, 1640create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1673 unsigned int context, re_hashval_t hash) 1641 unsigned int context, re_hashval_t hash)
1674{ 1642{
@@ -1677,10 +1645,10 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1677 re_dfastate_t *newstate; 1645 re_dfastate_t *newstate;
1678 1646
1679 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); 1647 newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
1680 if (BE (newstate == NULL, 0)) 1648 if (__glibc_unlikely (newstate == NULL))
1681 return NULL; 1649 return NULL;
1682 err = re_node_set_init_copy (&newstate->nodes, nodes); 1650 err = re_node_set_init_copy (&newstate->nodes, nodes);
1683 if (BE (err != REG_NOERROR, 0)) 1651 if (__glibc_unlikely (err != REG_NOERROR))
1684 { 1652 {
1685 re_free (newstate); 1653 re_free (newstate);
1686 return NULL; 1654 return NULL;
@@ -1697,9 +1665,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1697 1665
1698 if (type == CHARACTER && !constraint) 1666 if (type == CHARACTER && !constraint)
1699 continue; 1667 continue;
1700#ifdef RE_ENABLE_I18N
1701 newstate->accept_mb |= node->accept_mb; 1668 newstate->accept_mb |= node->accept_mb;
1702#endif /* RE_ENABLE_I18N */
1703 1669
1704 /* If the state has the halt node, the state is a halt state. */ 1670 /* If the state has the halt node, the state is a halt state. */
1705 if (type == END_OF_RE) 1671 if (type == END_OF_RE)
@@ -1711,15 +1677,19 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1711 { 1677 {
1712 if (newstate->entrance_nodes == &newstate->nodes) 1678 if (newstate->entrance_nodes == &newstate->nodes)
1713 { 1679 {
1714 newstate->entrance_nodes = re_malloc (re_node_set, 1); 1680 re_node_set *entrance_nodes = re_malloc (re_node_set, 1);
1715 if (BE (newstate->entrance_nodes == NULL, 0)) 1681 if (__glibc_unlikely (entrance_nodes == NULL))
1716 { 1682 {
1717 free_state (newstate); 1683 free_state (newstate);
1718 return NULL; 1684 return NULL;
1719 } 1685 }
1686 newstate->entrance_nodes = entrance_nodes;
1720 if (re_node_set_init_copy (newstate->entrance_nodes, nodes) 1687 if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
1721 != REG_NOERROR) 1688 != REG_NOERROR)
1722 return NULL; 1689 {
1690 free_state (newstate);
1691 return NULL;
1692 }
1723 nctx_nodes = 0; 1693 nctx_nodes = 0;
1724 newstate->has_constraint = 1; 1694 newstate->has_constraint = 1;
1725 } 1695 }
@@ -1732,7 +1702,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1732 } 1702 }
1733 } 1703 }
1734 err = register_state (dfa, newstate, hash); 1704 err = register_state (dfa, newstate, hash);
1735 if (BE (err != REG_NOERROR, 0)) 1705 if (__glibc_unlikely (err != REG_NOERROR))
1736 { 1706 {
1737 free_state (newstate); 1707 free_state (newstate);
1738 newstate = NULL; 1708 newstate = NULL;