1
/* Extended regular expression matching and search library.
2
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3
Free Software Foundation, Inc.
4
This file is part of the GNU C Library.
5
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License along
18
with this program; if not, write to the Free Software Foundation,
19
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21
#ifndef _REGEX_INTERNAL_H
22
#define _REGEX_INTERNAL_H 1
24
/* In case that the system doesn't have isblank(). */
25
#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
26
# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
30
# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
31
# define _RE_DEFINE_LOCALE_FUNCTIONS 1
32
# include <locale/localeinfo.h>
33
# include <locale/elem-hash.h>
34
# include <locale/coll-lookup.h>
38
/* This is for other GNU distributions with internationalized messages. */
39
#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
43
# define gettext(msgid) \
44
INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
47
# define gettext(msgid) (msgid)
51
/* This define is so xgettext can find the internationalizable
53
# define gettext_noop(String) String
56
/* For loser systems without the definition. */
58
# define SIZE_MAX ((size_t) -1)
61
#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || defined (_LIBC)
62
# define RE_ENABLE_I18N
66
# define BE(expr, val) __builtin_expect (expr, val)
68
# define BE(expr, val) (expr)
74
/* Number of ASCII characters. */
75
#define ASCII_CHARS 0x80
77
/* Number of single byte characters. */
78
#define SBC_MAX (UCHAR_MAX + 1)
80
#define COLL_ELEM_LEN_MAX 8
82
/* The character which represents newline. */
83
#define NEWLINE_CHAR '\n'
84
#define WIDE_NEWLINE_CHAR L'\n'
86
/* Rename to standard API for using out of glibc. */
88
# define __wctype wctype
89
# define __iswctype iswctype
90
# define __btowc btowc
91
# define __wcrtomb wcrtomb
92
# define __mbrtowc mbrtowc
93
# define __regfree regfree
94
# define attribute_hidden
95
#endif /* not _LIBC */
97
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
98
# define __attribute(arg) __attribute__ (arg)
100
# define __attribute(arg)
103
typedef __re_idx_t Idx;
105
/* Special return value for failure to match. */
106
#define REG_MISSING ((Idx) -1)
108
/* Special return value for internal error. */
109
#define REG_ERROR ((Idx) -2)
111
/* Test whether N is a valid index, and is not one of the above. */
112
#ifdef _REGEX_LARGE_OFFSETS
113
# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR)
115
# define REG_VALID_INDEX(n) (0 <= (n))
118
/* Test whether N is a valid nonzero index. */
119
#ifdef _REGEX_LARGE_OFFSETS
120
# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1))
122
# define REG_VALID_NONZERO_INDEX(n) (0 < (n))
125
/* A hash value, suitable for computing hash tables. */
126
typedef __re_size_t re_hashval_t;
128
/* An integer used to represent a set of bits. It must be unsigned,
129
and must be at least as wide as unsigned int. */
130
typedef unsigned long int bitset_word_t;
131
/* All bits set in a bitset_word_t. */
132
#define BITSET_WORD_MAX ULONG_MAX
134
/* Number of bits in a bitset_word_t. For portability to hosts with
135
padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)';
136
instead, deduce it directly from BITSET_WORD_MAX. Avoid
137
greater-than-32-bit integers and unconditional shifts by more than
138
31 bits, as they're not portable. */
139
#if BITSET_WORD_MAX == 0xffffffffUL
140
# define BITSET_WORD_BITS 32
141
#elif BITSET_WORD_MAX >> 31 >> 4 == 1
142
# define BITSET_WORD_BITS 36
143
#elif BITSET_WORD_MAX >> 31 >> 16 == 1
144
# define BITSET_WORD_BITS 48
145
#elif BITSET_WORD_MAX >> 31 >> 28 == 1
146
# define BITSET_WORD_BITS 60
147
#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1
148
# define BITSET_WORD_BITS 64
149
#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1
150
# define BITSET_WORD_BITS 72
151
#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1
152
# define BITSET_WORD_BITS 128
153
#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1
154
# define BITSET_WORD_BITS 256
155
#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1
156
# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */
157
# if BITSET_WORD_BITS <= SBC_MAX
158
# error "Invalid SBC_MAX"
161
# error "Add case for new bitset_word_t size"
164
/* Number of bitset_word_t values in a bitset_t. */
165
#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
167
typedef bitset_word_t bitset_t[BITSET_WORDS];
168
typedef bitset_word_t *re_bitset_ptr_t;
169
typedef const bitset_word_t *re_const_bitset_ptr_t;
171
#define PREV_WORD_CONSTRAINT 0x0001
172
#define PREV_NOTWORD_CONSTRAINT 0x0002
173
#define NEXT_WORD_CONSTRAINT 0x0004
174
#define NEXT_NOTWORD_CONSTRAINT 0x0008
175
#define PREV_NEWLINE_CONSTRAINT 0x0010
176
#define NEXT_NEWLINE_CONSTRAINT 0x0020
177
#define PREV_BEGBUF_CONSTRAINT 0x0040
178
#define NEXT_ENDBUF_CONSTRAINT 0x0080
179
#define WORD_DELIM_CONSTRAINT 0x0100
180
#define NOT_WORD_DELIM_CONSTRAINT 0x0200
184
INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
185
WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
186
WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
187
INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
188
LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
189
LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
190
BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
191
BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
192
WORD_DELIM = WORD_DELIM_CONSTRAINT,
193
NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
207
/* Node type, These are used by token, node, tree. */
213
#ifdef RE_ENABLE_I18N
216
#endif /* RE_ENABLE_I18N */
218
/* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
219
when the debugger shows values of this enum type. */
220
#define EPSILON_BIT 8
221
OP_OPEN_SUBEXP = EPSILON_BIT | 0,
222
OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
223
OP_ALT = EPSILON_BIT | 2,
224
OP_DUP_ASTERISK = EPSILON_BIT | 3,
225
ANCHOR = EPSILON_BIT | 4,
227
/* Tree type, these are used only by tree. */
231
/* Token type, these are used only by token. */
243
OP_CLOSE_EQUIV_CLASS,
254
#ifdef RE_ENABLE_I18N
257
/* Multibyte characters. */
260
/* Collating symbols. */
265
/* Equivalence classes. */
267
int32_t *equiv_classes;
270
/* Range expressions. */
272
uint32_t *range_starts;
273
uint32_t *range_ends;
274
# else /* not _LIBC */
275
wchar_t *range_starts;
277
# endif /* not _LIBC */
279
/* Character classes. */
280
wctype_t *char_classes;
282
/* If this character set is the non-matching list. */
283
unsigned int non_match : 1;
285
/* # of multibyte characters. */
288
/* # of collating symbols. */
291
/* # of equivalence classes. */
294
/* # of range expressions. */
297
/* # of character classes. */
300
#endif /* RE_ENABLE_I18N */
306
unsigned char c; /* for CHARACTER */
307
re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */
308
#ifdef RE_ENABLE_I18N
309
re_charset_t *mbcset; /* for COMPLEX_BRACKET */
310
#endif /* RE_ENABLE_I18N */
311
Idx idx; /* for BACK_REF */
312
re_context_type ctx_type; /* for ANCHOR */
314
#if __GNUC__ >= 2 && !__STRICT_ANSI__
315
re_token_type_t type : 8;
317
re_token_type_t type;
319
unsigned int constraint : 10; /* context constraint */
320
unsigned int duplicated : 1;
321
unsigned int opt_subexp : 1;
322
#ifdef RE_ENABLE_I18N
323
unsigned int accept_mb : 1;
324
/* These 2 bits can be moved into the union if needed (e.g. if running out
325
of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */
326
unsigned int mb_partial : 1;
328
unsigned int word_char : 1;
331
#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
335
/* Indicate the raw buffer which is the original string passed as an
336
argument of regexec(), re_search(), etc.. */
337
const unsigned char *raw_mbs;
338
/* Store the multibyte string. In case of "case insensitive mode" like
339
REG_ICASE, upper cases of the string are stored, otherwise MBS points
340
the same address that RAW_MBS points. */
342
#ifdef RE_ENABLE_I18N
343
/* Store the wide character string which is corresponding to MBS. */
348
/* Index in RAW_MBS. Each character mbs[i] corresponds to
349
raw_mbs[raw_mbs_idx + i]. */
351
/* The length of the valid characters in the buffers. */
353
/* The corresponding number of bytes in raw_mbs array. */
355
/* The length of the buffers MBS and WCS. */
357
/* The index in MBS, which is updated by re_string_fetch_byte. */
359
/* length of RAW_MBS array. */
361
/* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */
363
/* End of the buffer may be shorter than its length in the cases such
364
as re_match_2, re_search_2. Then, we use STOP for end of the buffer
367
/* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */
370
/* The context of mbs[0]. We store the context independently, since
371
the context of mbs[0] may be different from raw_mbs[0], which is
372
the beginning of the input string. */
373
unsigned int tip_context;
374
/* The translation passed as a part of an argument of re_compile_pattern. */
375
RE_TRANSLATE_TYPE trans;
376
/* Copy of re_dfa_t's word_char. */
377
re_const_bitset_ptr_t word_char;
378
/* true if REG_ICASE. */
380
unsigned char is_utf8;
381
unsigned char map_notascii;
382
unsigned char mbs_allocated;
383
unsigned char offsets_needed;
384
unsigned char newline_anchor;
385
unsigned char word_ops_used;
388
typedef struct re_string_t re_string_t;
392
typedef struct re_dfa_t re_dfa_t;
395
# if defined __i386__ && !defined __EMX__
396
# define internal_function __attribute ((regparm (3), stdcall))
398
# define internal_function
402
static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
405
#ifdef RE_ENABLE_I18N
406
static void build_wcs_buffer (re_string_t *pstr) internal_function;
407
static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr)
409
#endif /* RE_ENABLE_I18N */
410
static void build_upper_buffer (re_string_t *pstr) internal_function;
411
static void re_string_translate_buffer (re_string_t *pstr) internal_function;
412
static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
414
internal_function __attribute ((pure));
415
#define re_string_peek_byte(pstr, offset) \
416
((pstr)->mbs[(pstr)->cur_idx + offset])
417
#define re_string_fetch_byte(pstr) \
418
((pstr)->mbs[(pstr)->cur_idx++])
419
#define re_string_first_byte(pstr, idx) \
420
((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
421
#define re_string_is_single_byte_char(pstr, idx) \
422
((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
423
|| (pstr)->wcs[(idx) + 1] != WEOF))
424
#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
425
#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
426
#define re_string_get_buffer(pstr) ((pstr)->mbs)
427
#define re_string_length(pstr) ((pstr)->len)
428
#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
429
#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
430
#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
436
/* The OS usually guarantees only one guard page at the bottom of the stack,
437
and a page size can be as small as 4096 bytes. So we cannot safely
438
allocate anything larger than 4096 bytes. Also care for the possibility
439
of a few compiler-allocated temporary stack slots. */
440
# define __libc_use_alloca(n) ((n) < 4032)
442
/* alloca is implemented with malloc, so just use malloc. */
443
# define __libc_use_alloca(n) 0
448
# define MAX(a,b) ((a) < (b) ? (b) : (a))
451
#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
452
#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
453
#define re_free(p) free (p)
457
struct bin_tree_t *parent;
458
struct bin_tree_t *left;
459
struct bin_tree_t *right;
460
struct bin_tree_t *first;
461
struct bin_tree_t *next;
465
/* `node_idx' is the index in dfa->nodes, if `type' == 0.
466
Otherwise `type' indicate the type of this node. */
469
typedef struct bin_tree_t bin_tree_t;
471
#define BIN_TREE_STORAGE_SIZE \
472
((1024 - sizeof (void *)) / sizeof (bin_tree_t))
474
struct bin_tree_storage_t
476
struct bin_tree_storage_t *next;
477
bin_tree_t data[BIN_TREE_STORAGE_SIZE];
479
typedef struct bin_tree_storage_t bin_tree_storage_t;
481
#define CONTEXT_WORD 1
482
#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
483
#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
484
#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
486
#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
487
#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
488
#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
489
#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
490
#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
492
#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
493
#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
494
#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
495
#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
497
#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
498
((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
499
|| ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
500
|| ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
501
|| ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
503
#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
504
((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
505
|| (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
506
|| (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
507
|| (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
513
re_node_set non_eps_nodes;
514
re_node_set inveclosure;
515
re_node_set *entrance_nodes;
516
struct re_dfastate_t **trtable, **word_trtable;
517
unsigned int context : 4;
518
unsigned int halt : 1;
519
/* If this state can accept `multi byte'.
520
Note that we refer to multibyte characters, and multi character
521
collating elements as `multi byte'. */
522
unsigned int accept_mb : 1;
523
/* If this state has backreference node(s). */
524
unsigned int has_backref : 1;
525
unsigned int has_constraint : 1;
527
typedef struct re_dfastate_t re_dfastate_t;
529
struct re_state_table_entry
533
re_dfastate_t **array;
536
/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */
542
re_dfastate_t **array;
545
/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */
550
Idx str_idx; /* The position NODE match at. */
552
} re_sub_match_last_t;
554
/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
555
And information about the node, whose type is OP_CLOSE_SUBEXP,
556
corresponding to NODE is stored in LASTS. */
563
Idx alasts; /* Allocation size of LASTS. */
564
Idx nlasts; /* The number of LASTS. */
565
re_sub_match_last_t **lasts;
566
} re_sub_match_top_t;
568
struct re_backref_cache_entry
576
unsigned short int eps_reachable_subexps_map;
581
/* The string object corresponding to the input string. */
583
#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
584
const re_dfa_t *const dfa;
588
/* EFLAGS of the argument of regexec. */
590
/* Where the matching ends. */
593
/* The state log used by the matcher. */
594
re_dfastate_t **state_log;
596
/* Back reference cache. */
599
struct re_backref_cache_entry *bkref_ents;
603
re_sub_match_top_t **sub_tops;
604
} re_match_context_t;
608
re_dfastate_t **sifted_states;
609
re_dfastate_t **limited_states;
615
struct re_fail_stack_ent_t
620
re_node_set eps_via_nodes;
623
struct re_fail_stack_t
627
struct re_fail_stack_ent_t *stack;
638
re_node_set *eclosures;
639
re_node_set *inveclosures;
640
struct re_state_table_entry *state_table;
641
re_dfastate_t *init_state;
642
re_dfastate_t *init_state_word;
643
re_dfastate_t *init_state_nl;
644
re_dfastate_t *init_state_begbuf;
645
bin_tree_t *str_tree;
646
bin_tree_storage_t *str_tree_storage;
647
re_bitset_ptr_t sb_char;
648
int str_tree_storage_idx;
650
/* number of subexpressions `re_nsub' is in regex_t. */
651
re_hashval_t state_hash_mask;
653
Idx nbackref; /* The number of backreference in this dfa. */
655
/* Bitmap expressing which backreference is used. */
656
bitset_word_t used_bkref_map;
657
bitset_word_t completed_bkref_map;
659
unsigned int has_plural_match : 1;
660
/* If this dfa has "multibyte node", which is a backreference or
661
a node which can accept multibyte character or multi character
662
collating element. */
663
unsigned int has_mb_node : 1;
664
unsigned int is_utf8 : 1;
665
unsigned int map_notascii : 1;
666
unsigned int word_ops_used : 1;
675
__libc_lock_define (, lock)
679
#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
680
#define re_node_set_remove(set,id) \
681
(re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
682
#define re_node_set_empty(p) ((p)->nelem = 0)
683
#define re_node_set_free(set) re_free ((set)->elems)
697
bracket_elem_type type;
707
/* Inline functions for bitset_t operation. */
710
bitset_set (bitset_t set, Idx i)
712
set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
716
bitset_clear (bitset_t set, Idx i)
718
set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
722
bitset_contain (const bitset_t set, Idx i)
724
return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
728
bitset_empty (bitset_t set)
730
memset (set, '\0', sizeof (bitset_t));
734
bitset_set_all (bitset_t set)
736
memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
737
if (SBC_MAX % BITSET_WORD_BITS != 0)
738
set[BITSET_WORDS - 1] =
739
((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
743
bitset_copy (bitset_t dest, const bitset_t src)
745
memcpy (dest, src, sizeof (bitset_t));
749
bitset_not (bitset_t set)
752
for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)
753
set[bitset_i] = ~set[bitset_i];
754
if (SBC_MAX % BITSET_WORD_BITS != 0)
755
set[BITSET_WORDS - 1] =
756
((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)
757
& ~set[BITSET_WORDS - 1]);
761
bitset_merge (bitset_t dest, const bitset_t src)
764
for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
765
dest[bitset_i] |= src[bitset_i];
769
bitset_mask (bitset_t dest, const bitset_t src)
772
for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
773
dest[bitset_i] &= src[bitset_i];
776
#ifdef RE_ENABLE_I18N
777
/* Inline functions for re_string. */
779
internal_function __attribute ((pure))
780
re_string_char_size_at (const re_string_t *pstr, Idx idx)
783
if (pstr->mb_cur_max == 1)
785
for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
786
if (pstr->wcs[idx + byte_idx] != WEOF)
792
internal_function __attribute ((pure))
793
re_string_wchar_at (const re_string_t *pstr, Idx idx)
795
if (pstr->mb_cur_max == 1)
796
return (wint_t) pstr->mbs[idx];
797
return (wint_t) pstr->wcs[idx];
801
internal_function __attribute ((pure))
802
re_string_elem_size_at (const re_string_t *pstr, Idx idx)
805
const unsigned char *p, *extra;
806
const int32_t *table, *indirect;
808
# include <locale/weight.h>
809
uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
813
table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
814
extra = (const unsigned char *)
815
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
816
indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
817
_NL_COLLATE_INDIRECTMB);
820
return p - pstr->mbs - idx;
826
#endif /* RE_ENABLE_I18N */
828
#endif /* _REGEX_INTERNAL_H */