/src/wget/lib/regex_internal.h
Line | Count | Source |
1 | | /* Extended regular expression matching and search library. |
2 | | Copyright (C) 2002-2026 Free Software Foundation, Inc. |
3 | | This file is part of the GNU C Library. |
4 | | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. |
5 | | |
6 | | The GNU C Library is free software; you can redistribute it and/or |
7 | | modify it under the terms of the GNU Lesser General Public |
8 | | License as published by the Free Software Foundation; either |
9 | | version 2.1 of the License, or (at your option) any later version. |
10 | | |
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 |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | Lesser General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU Lesser General Public |
17 | | License along with the GNU C Library; if not, see |
18 | | <https://www.gnu.org/licenses/>. */ |
19 | | |
20 | | #ifndef _REGEX_INTERNAL_H |
21 | | #define _REGEX_INTERNAL_H 1 |
22 | | |
23 | | #include <ctype.h> |
24 | | #include <stdio.h> |
25 | | #include <stdlib.h> |
26 | | #include <string.h> |
27 | | |
28 | | #include <langinfo.h> |
29 | | #include <locale.h> |
30 | | #include <stdckdint.h> |
31 | | #include <stdcountof.h> |
32 | | #include <stdint.h> |
33 | | |
34 | | #ifndef _LIBC |
35 | | # include <dynarray.h> |
36 | | #endif |
37 | | |
38 | | #include <intprops.h> |
39 | | #include <verify.h> |
40 | | |
41 | | #if defined DEBUG && DEBUG != 0 |
42 | | # include <assert.h> |
43 | | # define DEBUG_ASSERT(x) assert (x) |
44 | | #else |
45 | 0 | # define DEBUG_ASSERT(x) assume (x) |
46 | | #endif |
47 | | |
48 | | #ifdef _LIBC |
49 | | # include <libc-lock.h> |
50 | | # define lock_define(name) __libc_lock_define (, name) |
51 | | # define lock_init(lock) (__libc_lock_init (lock), 0) |
52 | | # define lock_fini(lock) ((void) 0) |
53 | | # define lock_lock(lock) __libc_lock_lock (lock) |
54 | | # define lock_unlock(lock) __libc_lock_unlock (lock) |
55 | | #elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD |
56 | | # include "glthread/lock.h" |
57 | | # define lock_define(name) gl_lock_define (, name) |
58 | | # define lock_init(lock) glthread_lock_init (&(lock)) |
59 | 0 | # define lock_fini(lock) glthread_lock_destroy (&(lock)) |
60 | 0 | # define lock_lock(lock) glthread_lock_lock (&(lock)) |
61 | 0 | # define lock_unlock(lock) glthread_lock_unlock (&(lock)) |
62 | | #elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD |
63 | | # include <pthread.h> |
64 | | # define lock_define(name) pthread_mutex_t name; |
65 | | # define lock_init(lock) pthread_mutex_init (&(lock), 0) |
66 | | # define lock_fini(lock) pthread_mutex_destroy (&(lock)) |
67 | | # define lock_lock(lock) pthread_mutex_lock (&(lock)) |
68 | | # define lock_unlock(lock) pthread_mutex_unlock (&(lock)) |
69 | | #else |
70 | | # define lock_define(name) |
71 | | # define lock_init(lock) 0 |
72 | | # define lock_fini(lock) ((void) 0) |
73 | | /* The 'dfa' avoids an "unused variable 'dfa'" warning from GCC. */ |
74 | | # define lock_lock(lock) ((void) dfa) |
75 | | # define lock_unlock(lock) ((void) 0) |
76 | | #endif |
77 | | |
78 | | /* In case that the system doesn't have isblank(). */ |
79 | | #if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) |
80 | | # define isblank(ch) ((ch) == ' ' || (ch) == '\t') |
81 | | #endif |
82 | | |
83 | | /* regex code assumes isascii has its usual numeric meaning, |
84 | | even if the portable character set uses EBCDIC encoding, |
85 | | and even if wint_t is wider than int. */ |
86 | | #ifndef _LIBC |
87 | | # undef isascii |
88 | 0 | # define isascii(c) (((c) & ~0x7f) == 0) |
89 | | #endif |
90 | | |
91 | | #ifdef _LIBC |
92 | | # ifndef _RE_DEFINE_LOCALE_FUNCTIONS |
93 | | # define _RE_DEFINE_LOCALE_FUNCTIONS 1 |
94 | | # include <locale/localeinfo.h> |
95 | | # include <locale/coll-lookup.h> |
96 | | # endif |
97 | | #endif |
98 | | |
99 | | /* This is for other GNU distributions with internationalized messages. */ |
100 | | #ifdef _LIBC |
101 | | # include <libintl.h> |
102 | | # undef gettext |
103 | | # define gettext(msgid) \ |
104 | | __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) |
105 | | # define gettext_noop(String) String |
106 | | #else |
107 | | # include "gettext.h" |
108 | | #endif |
109 | | |
110 | | /* Number of ASCII characters. */ |
111 | 0 | #define ASCII_CHARS 0x80 |
112 | | |
113 | | /* Number of single byte characters. */ |
114 | 0 | #define SBC_MAX (UCHAR_MAX + 1) |
115 | | |
116 | | #define COLL_ELEM_LEN_MAX 8 |
117 | | |
118 | | /* The character which represents newline. */ |
119 | 0 | #define NEWLINE_CHAR '\n' |
120 | 0 | #define WIDE_NEWLINE_CHAR L'\n' |
121 | | |
122 | | /* Use Gnulib <uchar.h> if outside glibc and not avoided by the app. */ |
123 | | #if defined _LIBC || defined _REGEX_AVOID_UCHAR_H |
124 | | # include <wchar.h> |
125 | | # include <wctype.h> |
126 | | #else |
127 | | # include <uchar.h> |
128 | | # undef wctype_t |
129 | 0 | # define wchar_t char32_t |
130 | 0 | # define wctype_t c32_type_test_t |
131 | | #endif |
132 | | |
133 | | #ifndef _LIBC |
134 | | # undef __wctype |
135 | | # undef __iswalnum |
136 | | # undef __iswctype |
137 | | # undef __towlower |
138 | | # undef __towupper |
139 | | # undef __btowc |
140 | | # undef __mbrtowc |
141 | | # undef __wcrtomb |
142 | | # undef __regfree |
143 | | # define __regfree regfree |
144 | | # ifdef _REGEX_AVOID_UCHAR_H |
145 | | # define __wctype wctype |
146 | | # define __iswalnum iswalnum |
147 | | # define __iswctype iswctype |
148 | | # define __towlower towlower |
149 | | # define __towupper towupper |
150 | | # define __btowc btowc |
151 | | # define __mbrtowc mbrtowc |
152 | | # define __wcrtomb wcrtomb |
153 | | # else |
154 | 0 | # define __wctype c32_get_type_test |
155 | 0 | # define __iswalnum c32isalnum |
156 | 0 | # define __iswctype c32_apply_type_test |
157 | | # define __towlower c32tolower |
158 | 0 | # define __towupper c32toupper |
159 | 0 | # define __btowc btoc32 |
160 | 0 | # define __mbrtowc mbrtoc32 |
161 | 0 | # define __wcrtomb c32rtomb |
162 | | # endif |
163 | | #endif /* not _LIBC */ |
164 | | |
165 | | /* Types related to integers. Unless protected by #ifdef _LIBC, the |
166 | | regex code should avoid exact-width types like int32_t and uint64_t |
167 | | as some non-GCC platforms lack them, an issue when this code is |
168 | | used in Gnulib. */ |
169 | | |
170 | | #ifndef ULONG_WIDTH |
171 | | # define ULONG_WIDTH REGEX_UINTEGER_WIDTH (ULONG_MAX) |
172 | | /* The number of usable bits in an unsigned integer type with maximum |
173 | | value MAX, as an int expression suitable in #if. Cover all known |
174 | | practical hosts. This implementation exploits the fact that MAX is |
175 | | 1 less than a power of 2, and merely counts the number of 1 bits in |
176 | | MAX; "COBn" means "count the number of 1 bits in the low-order n bits". */ |
177 | | # define REGEX_UINTEGER_WIDTH(max) REGEX_COB128 (max) |
178 | | # define REGEX_COB128(n) (REGEX_COB64 ((n) >> 31 >> 31 >> 2) + REGEX_COB64 (n)) |
179 | | # define REGEX_COB64(n) (REGEX_COB32 ((n) >> 31 >> 1) + REGEX_COB32 (n)) |
180 | | # define REGEX_COB32(n) (REGEX_COB16 ((n) >> 16) + REGEX_COB16 (n)) |
181 | | # define REGEX_COB16(n) (REGEX_COB8 ((n) >> 8) + REGEX_COB8 (n)) |
182 | | # define REGEX_COB8(n) (REGEX_COB4 ((n) >> 4) + REGEX_COB4 (n)) |
183 | | # define REGEX_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + ((n) & 1)) |
184 | | # if ULONG_MAX / 2 + 1 != 1ul << (ULONG_WIDTH - 1) |
185 | | # error "ULONG_MAX out of range" |
186 | | # endif |
187 | | #endif |
188 | | |
189 | | /* The type of indexes into strings. This is signed, not size_t, |
190 | | since the API requires indexes to fit in regoff_t anyway, and using |
191 | | signed integers makes the code a bit smaller and presumably faster. |
192 | | The traditional GNU regex implementation uses int for indexes. |
193 | | The POSIX-compatible implementation uses a possibly-wider type. |
194 | | The name 'Idx' is three letters to minimize the hassle of |
195 | | reindenting a lot of regex code that formerly used 'int'. */ |
196 | | typedef regoff_t Idx; |
197 | | #ifdef _REGEX_LARGE_OFFSETS |
198 | | # ifdef SSIZE_MAX |
199 | | # define IDX_MAX SSIZE_MAX |
200 | | # else |
201 | | # define IDX_MAX ((Idx) ((size_t) -1 / 2)) |
202 | | # endif |
203 | | #else |
204 | | # define IDX_MAX INT_MAX |
205 | | #endif |
206 | | |
207 | | /* A hash value, suitable for computing hash tables. */ |
208 | | typedef __re_size_t re_hashval_t; |
209 | | |
210 | | /* An integer used to represent a set of bits. It must be unsigned, |
211 | | and must be at least as wide as unsigned int. */ |
212 | | typedef unsigned long int bitset_word_t; |
213 | | /* All bits set in a bitset_word_t. */ |
214 | | #define BITSET_WORD_MAX ULONG_MAX |
215 | | /* Number of bits in a bitset_word_t. */ |
216 | 0 | #define BITSET_WORD_BITS ULONG_WIDTH |
217 | | |
218 | | /* Number of bitset_word_t values in a bitset_t. */ |
219 | 0 | #define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS) |
220 | | |
221 | | typedef bitset_word_t bitset_t[BITSET_WORDS]; |
222 | | typedef bitset_word_t *re_bitset_ptr_t; |
223 | | typedef const bitset_word_t *re_const_bitset_ptr_t; |
224 | | |
225 | 0 | #define PREV_WORD_CONSTRAINT 0x0001 |
226 | 0 | #define PREV_NOTWORD_CONSTRAINT 0x0002 |
227 | 0 | #define NEXT_WORD_CONSTRAINT 0x0004 |
228 | 0 | #define NEXT_NOTWORD_CONSTRAINT 0x0008 |
229 | 0 | #define PREV_NEWLINE_CONSTRAINT 0x0010 |
230 | 0 | #define NEXT_NEWLINE_CONSTRAINT 0x0020 |
231 | 0 | #define PREV_BEGBUF_CONSTRAINT 0x0040 |
232 | 0 | #define NEXT_ENDBUF_CONSTRAINT 0x0080 |
233 | | #define WORD_DELIM_CONSTRAINT 0x0100 |
234 | | #define NOT_WORD_DELIM_CONSTRAINT 0x0200 |
235 | | |
236 | | typedef enum |
237 | | { |
238 | | INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, |
239 | | WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, |
240 | | WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, |
241 | | INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, |
242 | | LINE_FIRST = PREV_NEWLINE_CONSTRAINT, |
243 | | LINE_LAST = NEXT_NEWLINE_CONSTRAINT, |
244 | | BUF_FIRST = PREV_BEGBUF_CONSTRAINT, |
245 | | BUF_LAST = NEXT_ENDBUF_CONSTRAINT, |
246 | | WORD_DELIM = WORD_DELIM_CONSTRAINT, |
247 | | NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT |
248 | | } re_context_type; |
249 | | |
250 | | typedef struct |
251 | | { |
252 | | Idx alloc; |
253 | | Idx nelem; |
254 | | Idx *elems; |
255 | | } re_node_set; |
256 | | |
257 | | typedef enum |
258 | | { |
259 | | NON_TYPE = 0, |
260 | | |
261 | | /* Node type, These are used by token, node, tree. */ |
262 | | CHARACTER = 1, |
263 | | END_OF_RE = 2, |
264 | | SIMPLE_BRACKET = 3, |
265 | | OP_BACK_REF = 4, |
266 | | OP_PERIOD = 5, |
267 | | COMPLEX_BRACKET = 6, |
268 | | OP_UTF8_PERIOD = 7, |
269 | | |
270 | | /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used |
271 | | when the debugger shows values of this enum type. */ |
272 | 0 | #define EPSILON_BIT 8 |
273 | | OP_OPEN_SUBEXP = EPSILON_BIT | 0, |
274 | | OP_CLOSE_SUBEXP = EPSILON_BIT | 1, |
275 | | OP_ALT = EPSILON_BIT | 2, |
276 | | OP_DUP_ASTERISK = EPSILON_BIT | 3, |
277 | | ANCHOR = EPSILON_BIT | 4, |
278 | | |
279 | | /* Tree type, these are used only by tree. */ |
280 | | CONCAT = 16, |
281 | | SUBEXP = 17, |
282 | | |
283 | | /* Token type, these are used only by token. */ |
284 | | OP_DUP_PLUS = 18, |
285 | | OP_DUP_QUESTION, |
286 | | OP_OPEN_BRACKET, |
287 | | OP_CLOSE_BRACKET, |
288 | | OP_CHARSET_RANGE, |
289 | | OP_OPEN_DUP_NUM, |
290 | | OP_CLOSE_DUP_NUM, |
291 | | OP_NON_MATCH_LIST, |
292 | | OP_OPEN_COLL_ELEM, |
293 | | OP_CLOSE_COLL_ELEM, |
294 | | OP_OPEN_EQUIV_CLASS, |
295 | | OP_CLOSE_EQUIV_CLASS, |
296 | | OP_OPEN_CHAR_CLASS, |
297 | | OP_CLOSE_CHAR_CLASS, |
298 | | OP_WORD, |
299 | | OP_NOTWORD, |
300 | | OP_SPACE, |
301 | | OP_NOTSPACE, |
302 | | BACK_SLASH |
303 | | |
304 | | } re_token_type_t; |
305 | | |
306 | | typedef struct |
307 | | { |
308 | | /* Multibyte characters. */ |
309 | | wchar_t *mbchars; |
310 | | |
311 | | #ifdef _LIBC |
312 | | /* Collating symbols. */ |
313 | | int32_t *coll_syms; |
314 | | #endif |
315 | | |
316 | | #ifdef _LIBC |
317 | | /* Equivalence classes. */ |
318 | | int32_t *equiv_classes; |
319 | | #endif |
320 | | |
321 | | /* Range expressions. */ |
322 | | #ifdef _LIBC |
323 | | uint32_t *range_starts; |
324 | | uint32_t *range_ends; |
325 | | #else |
326 | | wchar_t *range_starts; |
327 | | wchar_t *range_ends; |
328 | | #endif |
329 | | |
330 | | /* Character classes. */ |
331 | | wctype_t *char_classes; |
332 | | |
333 | | /* If this character set is the non-matching list. */ |
334 | | unsigned int non_match : 1; |
335 | | |
336 | | /* # of multibyte characters. */ |
337 | | Idx nmbchars; |
338 | | |
339 | | /* # of collating symbols. */ |
340 | | Idx ncoll_syms; |
341 | | |
342 | | /* # of equivalence classes. */ |
343 | | Idx nequiv_classes; |
344 | | |
345 | | /* # of range expressions. */ |
346 | | Idx nranges; |
347 | | |
348 | | /* # of character classes. */ |
349 | | Idx nchar_classes; |
350 | | } re_charset_t; |
351 | | |
352 | | typedef struct |
353 | | { |
354 | | union |
355 | | { |
356 | | unsigned char c; /* for CHARACTER */ |
357 | | re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ |
358 | | re_charset_t *mbcset; /* for COMPLEX_BRACKET */ |
359 | | Idx idx; /* for BACK_REF */ |
360 | | re_context_type ctx_type; /* for ANCHOR */ |
361 | | } opr; |
362 | | #if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__ |
363 | | re_token_type_t type : 8; |
364 | | #else |
365 | | re_token_type_t type; |
366 | | #endif |
367 | | unsigned int constraint : 10; /* context constraint */ |
368 | | unsigned int duplicated : 1; |
369 | | unsigned int opt_subexp : 1; |
370 | | unsigned int accept_mb : 1; |
371 | | /* These 2 bits can be moved into the union if needed (e.g. if running out |
372 | | of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ |
373 | | unsigned int mb_partial : 1; |
374 | | unsigned int word_char : 1; |
375 | | } re_token_t; |
376 | | |
377 | 0 | #define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT) |
378 | | |
379 | | struct re_string_t |
380 | | { |
381 | | /* Indicate the raw buffer which is the original string passed as an |
382 | | argument of regexec(), re_search(), etc.. */ |
383 | | const unsigned char *raw_mbs; |
384 | | /* Store the multibyte string. In case of "case insensitive mode" like |
385 | | REG_ICASE, upper cases of the string are stored, otherwise MBS points |
386 | | the same address that RAW_MBS points. */ |
387 | | unsigned char *mbs; |
388 | | /* Store the wide character string which is corresponding to MBS. */ |
389 | | wint_t *wcs; |
390 | | Idx *offsets; |
391 | | mbstate_t cur_state; |
392 | | /* Index in RAW_MBS. Each character mbs[i] corresponds to |
393 | | raw_mbs[raw_mbs_idx + i]. */ |
394 | | Idx raw_mbs_idx; |
395 | | /* The length of the valid characters in the buffers. */ |
396 | | Idx valid_len; |
397 | | /* The corresponding number of bytes in raw_mbs array. */ |
398 | | Idx valid_raw_len; |
399 | | /* The length of the buffers MBS and WCS. */ |
400 | | Idx bufs_len; |
401 | | /* The index in MBS, which is updated by re_string_fetch_byte. */ |
402 | | Idx cur_idx; |
403 | | /* length of RAW_MBS array. */ |
404 | | Idx raw_len; |
405 | | /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */ |
406 | | Idx len; |
407 | | /* End of the buffer may be shorter than its length in the cases such |
408 | | as re_match_2, re_search_2. Then, we use STOP for end of the buffer |
409 | | instead of LEN. */ |
410 | | Idx raw_stop; |
411 | | /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */ |
412 | | Idx stop; |
413 | | |
414 | | /* The context of mbs[0]. We store the context independently, since |
415 | | the context of mbs[0] may be different from raw_mbs[0], which is |
416 | | the beginning of the input string. */ |
417 | | unsigned int tip_context; |
418 | | /* The translation passed as a part of an argument of re_compile_pattern. */ |
419 | | RE_TRANSLATE_TYPE trans; |
420 | | /* Copy of re_dfa_t's word_char. */ |
421 | | re_const_bitset_ptr_t word_char; |
422 | | /* true if REG_ICASE. */ |
423 | | unsigned char icase; |
424 | | unsigned char is_utf8; |
425 | | unsigned char map_notascii; |
426 | | unsigned char mbs_allocated; |
427 | | unsigned char offsets_needed; |
428 | | unsigned char newline_anchor; |
429 | | unsigned char word_ops_used; |
430 | | int mb_cur_max; |
431 | | }; |
432 | | typedef struct re_string_t re_string_t; |
433 | | |
434 | | |
435 | | struct re_dfa_t; |
436 | | typedef struct re_dfa_t re_dfa_t; |
437 | | |
438 | | #ifndef _LIBC |
439 | | # define IS_IN(libc) false |
440 | | #endif |
441 | | |
442 | | #define re_string_peek_byte(pstr, offset) \ |
443 | 0 | ((pstr)->mbs[(pstr)->cur_idx + offset]) |
444 | | #define re_string_fetch_byte(pstr) \ |
445 | 0 | ((pstr)->mbs[(pstr)->cur_idx++]) |
446 | | #define re_string_first_byte(pstr, idx) \ |
447 | 0 | ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF) |
448 | | #define re_string_is_single_byte_char(pstr, idx) \ |
449 | 0 | ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \ |
450 | 0 | || (pstr)->wcs[(idx) + 1] != WEOF)) |
451 | 0 | #define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx) |
452 | 0 | #define re_string_cur_idx(pstr) ((pstr)->cur_idx) |
453 | 0 | #define re_string_get_buffer(pstr) ((pstr)->mbs) |
454 | 0 | #define re_string_length(pstr) ((pstr)->len) |
455 | 0 | #define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx]) |
456 | 0 | #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) |
457 | 0 | #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) |
458 | | |
459 | | #ifndef MAX |
460 | 0 | # define MAX(a,b) ((a) < (b) ? (b) : (a)) |
461 | | #endif |
462 | | #ifndef MIN |
463 | 0 | # define MIN(a,b) ((a) < (b) ? (a) : (b)) |
464 | | #endif |
465 | | |
466 | | #if defined _LIBC || HAVE_MALLOC_0_NONNULL |
467 | 0 | # define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) |
468 | | #else |
469 | | # define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t) + ((n) == 0))) |
470 | | #endif |
471 | 0 | #define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) |
472 | 0 | #define re_free(p) free (p) |
473 | | |
474 | | struct bin_tree_t |
475 | | { |
476 | | struct bin_tree_t *parent; |
477 | | struct bin_tree_t *left; |
478 | | struct bin_tree_t *right; |
479 | | struct bin_tree_t *first; |
480 | | struct bin_tree_t *next; |
481 | | |
482 | | re_token_t token; |
483 | | |
484 | | /* 'node_idx' is the index in dfa->nodes, if 'type' == 0. |
485 | | Otherwise 'type' indicate the type of this node. */ |
486 | | Idx node_idx; |
487 | | }; |
488 | | typedef struct bin_tree_t bin_tree_t; |
489 | | |
490 | | #define BIN_TREE_STORAGE_SIZE \ |
491 | 0 | ((1024 - sizeof (void *)) / sizeof (bin_tree_t)) |
492 | | |
493 | | struct bin_tree_storage_t |
494 | | { |
495 | | struct bin_tree_storage_t *next; |
496 | | bin_tree_t data[BIN_TREE_STORAGE_SIZE]; |
497 | | }; |
498 | | typedef struct bin_tree_storage_t bin_tree_storage_t; |
499 | | |
500 | 0 | #define CONTEXT_WORD 1 |
501 | 0 | #define CONTEXT_NEWLINE (CONTEXT_WORD << 1) |
502 | 0 | #define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1) |
503 | 0 | #define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1) |
504 | | |
505 | 0 | #define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD) |
506 | 0 | #define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE) |
507 | 0 | #define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF) |
508 | 0 | #define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF) |
509 | 0 | #define IS_ORDINARY_CONTEXT(c) ((c) == 0) |
510 | | |
511 | 0 | #define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_') |
512 | 0 | #define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR) |
513 | 0 | #define IS_WIDE_WORD_CHAR(ch) (__iswalnum (ch) || (ch) == L'_') |
514 | 0 | #define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) |
515 | | |
516 | | #define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ |
517 | 0 | ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ |
518 | 0 | || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ |
519 | 0 | || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\ |
520 | 0 | || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context))) |
521 | | |
522 | | #define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \ |
523 | 0 | ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ |
524 | 0 | || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ |
525 | 0 | || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \ |
526 | 0 | || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context))) |
527 | | |
528 | | struct re_dfastate_t |
529 | | { |
530 | | re_hashval_t hash; |
531 | | re_node_set nodes; |
532 | | re_node_set non_eps_nodes; |
533 | | re_node_set inveclosure; |
534 | | re_node_set *entrance_nodes; |
535 | | struct re_dfastate_t **trtable, **word_trtable; |
536 | | unsigned int context : 4; |
537 | | unsigned int halt : 1; |
538 | | /* If this state can accept "multi byte". |
539 | | Note that we refer to multibyte characters, and multi character |
540 | | collating elements as "multi byte". */ |
541 | | unsigned int accept_mb : 1; |
542 | | /* If this state has backreference node(s). */ |
543 | | unsigned int has_backref : 1; |
544 | | unsigned int has_constraint : 1; |
545 | | }; |
546 | | typedef struct re_dfastate_t re_dfastate_t; |
547 | | |
548 | | struct re_state_table_entry |
549 | | { |
550 | | Idx num; |
551 | | Idx alloc; |
552 | | re_dfastate_t **array; |
553 | | }; |
554 | | |
555 | | /* Array type used in re_sub_match_last_t and re_sub_match_top_t. */ |
556 | | |
557 | | typedef struct |
558 | | { |
559 | | Idx next_idx; |
560 | | Idx alloc; |
561 | | re_dfastate_t **array; |
562 | | } state_array_t; |
563 | | |
564 | | /* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */ |
565 | | |
566 | | typedef struct |
567 | | { |
568 | | Idx node; |
569 | | Idx str_idx; /* The position NODE match at. */ |
570 | | state_array_t path; |
571 | | } re_sub_match_last_t; |
572 | | |
573 | | /* Store information about the node NODE whose type is OP_OPEN_SUBEXP. |
574 | | And information about the node, whose type is OP_CLOSE_SUBEXP, |
575 | | corresponding to NODE is stored in LASTS. */ |
576 | | |
577 | | typedef struct |
578 | | { |
579 | | Idx str_idx; |
580 | | Idx node; |
581 | | state_array_t *path; |
582 | | Idx alasts; /* Allocation size of LASTS. */ |
583 | | Idx nlasts; /* The number of LASTS. */ |
584 | | re_sub_match_last_t **lasts; |
585 | | } re_sub_match_top_t; |
586 | | |
587 | | struct re_backref_cache_entry |
588 | | { |
589 | | Idx node; |
590 | | Idx str_idx; |
591 | | Idx subexp_from; |
592 | | Idx subexp_to; |
593 | | bitset_word_t eps_reachable_subexps_map; |
594 | | char more; |
595 | | }; |
596 | | |
597 | | typedef struct |
598 | | { |
599 | | /* The string object corresponding to the input string. */ |
600 | | re_string_t input; |
601 | | const re_dfa_t *const dfa; |
602 | | /* EFLAGS of the argument of regexec. */ |
603 | | int eflags; |
604 | | /* Where the matching ends. */ |
605 | | Idx match_last; |
606 | | Idx last_node; |
607 | | /* The state log used by the matcher. */ |
608 | | re_dfastate_t **state_log; |
609 | | Idx state_log_top; |
610 | | /* Back reference cache. */ |
611 | | Idx nbkref_ents; |
612 | | Idx abkref_ents; |
613 | | struct re_backref_cache_entry *bkref_ents; |
614 | | int max_mb_elem_len; |
615 | | Idx nsub_tops; |
616 | | Idx asub_tops; |
617 | | re_sub_match_top_t **sub_tops; |
618 | | } re_match_context_t; |
619 | | |
620 | | typedef struct |
621 | | { |
622 | | re_dfastate_t **sifted_states; |
623 | | re_dfastate_t **limited_states; |
624 | | Idx last_node; |
625 | | Idx last_str_idx; |
626 | | re_node_set limits; |
627 | | } re_sift_context_t; |
628 | | |
629 | | struct re_fail_stack_ent_t |
630 | | { |
631 | | Idx idx; |
632 | | Idx node; |
633 | | regmatch_t *regs; |
634 | | re_node_set eps_via_nodes; |
635 | | }; |
636 | | |
637 | | struct re_fail_stack_t |
638 | | { |
639 | | Idx num; |
640 | | Idx alloc; |
641 | | struct re_fail_stack_ent_t *stack; |
642 | | }; |
643 | | |
644 | | struct re_dfa_t |
645 | | { |
646 | | re_token_t *nodes; |
647 | | size_t nodes_alloc; |
648 | | size_t nodes_len; |
649 | | Idx *nexts; |
650 | | Idx *org_indices; |
651 | | re_node_set *edests; |
652 | | re_node_set *eclosures; |
653 | | re_node_set *inveclosures; |
654 | | struct re_state_table_entry *state_table; |
655 | | re_dfastate_t *init_state; |
656 | | re_dfastate_t *init_state_word; |
657 | | re_dfastate_t *init_state_nl; |
658 | | re_dfastate_t *init_state_begbuf; |
659 | | bin_tree_t *str_tree; |
660 | | bin_tree_storage_t *str_tree_storage; |
661 | | re_bitset_ptr_t sb_char; |
662 | | int str_tree_storage_idx; |
663 | | |
664 | | /* number of subexpressions 're_nsub' is in regex_t. */ |
665 | | re_hashval_t state_hash_mask; |
666 | | Idx init_node; |
667 | | Idx nbackref; /* The number of backreference in this dfa. */ |
668 | | |
669 | | /* Bitmap expressing which backreference is used. */ |
670 | | bitset_word_t used_bkref_map; |
671 | | bitset_word_t completed_bkref_map; |
672 | | |
673 | | unsigned int has_plural_match : 1; |
674 | | /* If this dfa has "multibyte node", which is a backreference or |
675 | | a node which can accept multibyte character or multi character |
676 | | collating element. */ |
677 | | unsigned int has_mb_node : 1; |
678 | | unsigned int is_utf8 : 1; |
679 | | unsigned int map_notascii : 1; |
680 | | unsigned int word_ops_used : 1; |
681 | | int mb_cur_max; |
682 | | bitset_t word_char; |
683 | | reg_syntax_t syntax; |
684 | | Idx *subexp_map; |
685 | | #ifdef DEBUG |
686 | | char* re_str; |
687 | | #endif |
688 | | lock_define (lock) |
689 | | }; |
690 | | |
691 | 0 | #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) |
692 | | #define re_node_set_remove(set,id) \ |
693 | 0 | (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) |
694 | 0 | #define re_node_set_empty(p) ((p)->nelem = 0) |
695 | 0 | #define re_node_set_free(set) re_free ((set)->elems) |
696 | | |
697 | | |
698 | | typedef enum |
699 | | { |
700 | | SB_CHAR, |
701 | | MB_CHAR, |
702 | | EQUIV_CLASS, |
703 | | COLL_SYM, |
704 | | CHAR_CLASS |
705 | | } bracket_elem_type; |
706 | | |
707 | | typedef struct |
708 | | { |
709 | | bracket_elem_type type; |
710 | | union |
711 | | { |
712 | | unsigned char ch; |
713 | | unsigned char *name; |
714 | | wchar_t wch; |
715 | | } opr; |
716 | | } bracket_elem_t; |
717 | | |
718 | | |
719 | | /* Functions for bitset_t operation. */ |
720 | | |
721 | | static inline void |
722 | | bitset_set (bitset_t set, Idx i) |
723 | 0 | { |
724 | 0 | set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; |
725 | 0 | } |
726 | | |
727 | | static inline void |
728 | | bitset_clear (bitset_t set, Idx i) |
729 | 0 | { |
730 | 0 | set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); |
731 | 0 | } |
732 | | |
733 | | static inline bool |
734 | | bitset_contain (const bitset_t set, Idx i) |
735 | 0 | { |
736 | 0 | return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; |
737 | 0 | } |
738 | | |
739 | | static inline void |
740 | | bitset_empty (bitset_t set) |
741 | 0 | { |
742 | 0 | memset (set, '\0', sizeof (bitset_t)); |
743 | 0 | } |
744 | | |
745 | | static inline void |
746 | | bitset_set_all (bitset_t set) |
747 | 0 | { |
748 | 0 | memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); |
749 | 0 | if (SBC_MAX % BITSET_WORD_BITS != 0) |
750 | 0 | set[BITSET_WORDS - 1] = |
751 | 0 | ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; |
752 | 0 | } |
753 | | |
754 | | static inline void |
755 | | bitset_copy (bitset_t dest, const bitset_t src) |
756 | 0 | { |
757 | 0 | memcpy (dest, src, sizeof (bitset_t)); |
758 | 0 | } |
759 | | |
760 | | static inline void |
761 | | bitset_not (bitset_t set) |
762 | 0 | { |
763 | 0 | int bitset_i; |
764 | 0 | for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i) |
765 | 0 | set[bitset_i] = ~set[bitset_i]; |
766 | 0 | if (SBC_MAX % BITSET_WORD_BITS != 0) |
767 | 0 | set[BITSET_WORDS - 1] = |
768 | 0 | ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1) |
769 | 0 | & ~set[BITSET_WORDS - 1]); |
770 | 0 | } |
771 | | |
772 | | static inline void |
773 | | bitset_merge (bitset_t dest, const bitset_t src) |
774 | 0 | { |
775 | 0 | int bitset_i; |
776 | 0 | for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) |
777 | 0 | dest[bitset_i] |= src[bitset_i]; |
778 | 0 | } |
779 | | |
780 | | static inline void |
781 | | bitset_mask (bitset_t dest, const bitset_t src) |
782 | 0 | { |
783 | 0 | int bitset_i; |
784 | 0 | for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) |
785 | 0 | dest[bitset_i] &= src[bitset_i]; |
786 | 0 | } |
787 | | |
788 | | /* Functions for re_string. */ |
789 | | static int |
790 | | __attribute__ ((pure, unused)) |
791 | | re_string_char_size_at (const re_string_t *pstr, Idx idx) |
792 | 0 | { |
793 | 0 | int byte_idx; |
794 | 0 | if (pstr->mb_cur_max == 1) |
795 | 0 | return 1; |
796 | 0 | for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) |
797 | 0 | if (pstr->wcs[idx + byte_idx] != WEOF) |
798 | 0 | break; |
799 | 0 | return byte_idx; |
800 | 0 | } |
801 | | |
802 | | static wint_t |
803 | | __attribute__ ((pure, unused)) |
804 | | re_string_wchar_at (const re_string_t *pstr, Idx idx) |
805 | 0 | { |
806 | 0 | if (pstr->mb_cur_max == 1) |
807 | 0 | return pstr->mbs[idx]; |
808 | 0 | return pstr->wcs[idx]; |
809 | 0 | } |
810 | | |
811 | | #ifdef _LIBC |
812 | | # include <locale/weight.h> |
813 | | #endif |
814 | | |
815 | | static int |
816 | | __attribute__ ((pure, unused)) |
817 | | re_string_elem_size_at (const re_string_t *pstr, Idx idx) |
818 | 0 | { |
819 | | #ifdef _LIBC |
820 | | const unsigned char *p, *extra; |
821 | | const int32_t *table, *indirect; |
822 | | uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); |
823 | | |
824 | | if (nrules != 0) |
825 | | { |
826 | | table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); |
827 | | extra = (const unsigned char *) |
828 | | _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); |
829 | | indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, |
830 | | _NL_COLLATE_INDIRECTMB); |
831 | | p = pstr->mbs + idx; |
832 | | findidx (table, indirect, extra, &p, pstr->len - idx); |
833 | | return p - pstr->mbs - idx; |
834 | | } |
835 | | #endif /* _LIBC */ |
836 | |
|
837 | 0 | return 1; |
838 | 0 | } |
839 | | |
840 | | #ifdef _LIBC |
841 | | # if __glibc_has_attribute (__fallthrough__) |
842 | | # define FALLTHROUGH __attribute__ ((__fallthrough__)) |
843 | | # else |
844 | | # define FALLTHROUGH ((void) 0) |
845 | | # endif |
846 | | #else |
847 | | # include "attribute.h" |
848 | | #endif |
849 | | |
850 | | #endif /* _REGEX_INTERNAL_H */ |