17 |
with this program; if not, write to the Free Software Foundation, |
with this program; if not, write to the Free Software Foundation, |
18 |
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
19 |
|
|
20 |
static void re_string_construct_common (const char *str, int len, |
static void re_string_construct_common (const char *str, Idx len, |
21 |
re_string_t *pstr, |
re_string_t *pstr, |
22 |
RE_TRANSLATE_TYPE trans, int icase, |
REG_TRANSLATE_TYPE trans, bool icase, |
23 |
const re_dfa_t *dfa) internal_function; |
const re_dfa_t *dfa) internal_function; |
24 |
#ifdef RE_ENABLE_I18N |
static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, |
|
static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx, |
|
|
wint_t *last_wc) internal_function; |
|
|
#endif /* RE_ENABLE_I18N */ |
|
|
static reg_errcode_t register_state (re_dfa_t *dfa, re_dfastate_t *newstate, |
|
|
unsigned int hash) internal_function; |
|
|
static re_dfastate_t *create_ci_newstate (re_dfa_t *dfa, |
|
25 |
const re_node_set *nodes, |
const re_node_set *nodes, |
26 |
unsigned int hash) internal_function; |
re_hashval_t hash) internal_function; |
27 |
static re_dfastate_t *create_cd_newstate (re_dfa_t *dfa, |
static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, |
28 |
const re_node_set *nodes, |
const re_node_set *nodes, |
29 |
unsigned int context, |
unsigned int context, |
30 |
unsigned int hash) internal_function; |
re_hashval_t hash) internal_function; |
|
static unsigned int inline calc_state_hash (const re_node_set *nodes, |
|
|
unsigned int context) internal_function; |
|
31 |
|
|
32 |
/* Functions for string operation. */ |
/* Functions for string operation. */ |
33 |
|
|
35 |
re_string_reconstruct before using the object. */ |
re_string_reconstruct before using the object. */ |
36 |
|
|
37 |
static reg_errcode_t |
static reg_errcode_t |
38 |
re_string_allocate (pstr, str, len, init_len, trans, icase, dfa) |
internal_function |
39 |
re_string_t *pstr; |
re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, |
40 |
const char *str; |
REG_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) |
|
int len, init_len, icase; |
|
|
RE_TRANSLATE_TYPE trans; |
|
|
const re_dfa_t *dfa; |
|
41 |
{ |
{ |
42 |
reg_errcode_t ret; |
reg_errcode_t ret; |
43 |
int init_buf_len; |
Idx init_buf_len; |
44 |
|
|
45 |
/* Ensure at least one character fits into the buffers. */ |
/* Ensure at least one character fits into the buffers. */ |
46 |
if (init_len < dfa->mb_cur_max) |
if (init_len < dfa->mb_cur_max) |
63 |
/* This function allocate the buffers, and initialize them. */ |
/* This function allocate the buffers, and initialize them. */ |
64 |
|
|
65 |
static reg_errcode_t |
static reg_errcode_t |
66 |
re_string_construct (pstr, str, len, trans, icase, dfa) |
internal_function |
67 |
re_string_t *pstr; |
re_string_construct (re_string_t *pstr, const char *str, Idx len, |
68 |
const char *str; |
REG_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) |
|
int len, icase; |
|
|
RE_TRANSLATE_TYPE trans; |
|
|
const re_dfa_t *dfa; |
|
69 |
{ |
{ |
70 |
reg_errcode_t ret; |
reg_errcode_t ret; |
71 |
memset (pstr, '\0', sizeof (re_string_t)); |
memset (pstr, '\0', sizeof (re_string_t)); |
126 |
/* Helper functions for re_string_allocate, and re_string_construct. */ |
/* Helper functions for re_string_allocate, and re_string_construct. */ |
127 |
|
|
128 |
static reg_errcode_t |
static reg_errcode_t |
129 |
re_string_realloc_buffers (pstr, new_buf_len) |
internal_function |
130 |
re_string_t *pstr; |
re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) |
|
int new_buf_len; |
|
131 |
{ |
{ |
132 |
#ifdef RE_ENABLE_I18N |
#ifdef RE_ENABLE_I18N |
133 |
if (pstr->mb_cur_max > 1) |
if (pstr->mb_cur_max > 1) |
134 |
{ |
{ |
135 |
wint_t *new_array = re_realloc (pstr->wcs, wint_t, new_buf_len); |
wint_t *new_wcs = re_xrealloc (pstr->wcs, wint_t, new_buf_len); |
136 |
if (BE (new_array == NULL, 0)) |
if (BE (new_wcs == NULL, 0)) |
137 |
return REG_ESPACE; |
return REG_ESPACE; |
138 |
pstr->wcs = new_array; |
pstr->wcs = new_wcs; |
139 |
if (pstr->offsets != NULL) |
if (pstr->offsets != NULL) |
140 |
{ |
{ |
141 |
int *new_array = re_realloc (pstr->offsets, int, new_buf_len); |
Idx *new_offsets = re_xrealloc (pstr->offsets, Idx, new_buf_len); |
142 |
if (BE (new_array == NULL, 0)) |
if (BE (new_offsets == NULL, 0)) |
143 |
return REG_ESPACE; |
return REG_ESPACE; |
144 |
pstr->offsets = new_array; |
pstr->offsets = new_offsets; |
145 |
} |
} |
146 |
} |
} |
147 |
#endif /* RE_ENABLE_I18N */ |
#endif /* RE_ENABLE_I18N */ |
148 |
if (pstr->mbs_allocated) |
if (pstr->mbs_allocated) |
149 |
{ |
{ |
150 |
unsigned char *new_array = re_realloc (pstr->mbs, unsigned char, |
unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, |
151 |
new_buf_len); |
new_buf_len); |
152 |
if (BE (new_array == NULL, 0)) |
if (BE (new_mbs == NULL, 0)) |
153 |
return REG_ESPACE; |
return REG_ESPACE; |
154 |
pstr->mbs = new_array; |
pstr->mbs = new_mbs; |
155 |
} |
} |
156 |
pstr->bufs_len = new_buf_len; |
pstr->bufs_len = new_buf_len; |
157 |
return REG_NOERROR; |
return REG_NOERROR; |
159 |
|
|
160 |
|
|
161 |
static void |
static void |
162 |
re_string_construct_common (str, len, pstr, trans, icase, dfa) |
internal_function |
163 |
const char *str; |
re_string_construct_common (const char *str, Idx len, re_string_t *pstr, |
164 |
int len; |
REG_TRANSLATE_TYPE trans, bool icase, |
165 |
re_string_t *pstr; |
const re_dfa_t *dfa) |
|
RE_TRANSLATE_TYPE trans; |
|
|
int icase; |
|
|
const re_dfa_t *dfa; |
|
166 |
{ |
{ |
167 |
pstr->raw_mbs = (const unsigned char *) str; |
pstr->raw_mbs = (const unsigned char *) str; |
168 |
pstr->len = len; |
pstr->len = len; |
169 |
pstr->raw_len = len; |
pstr->raw_len = len; |
170 |
pstr->trans = (unsigned RE_TRANSLATE_TYPE) trans; |
pstr->trans = (unsigned REG_TRANSLATE_TYPE) trans; |
171 |
pstr->icase = icase ? 1 : 0; |
pstr->icase = icase; |
172 |
pstr->mbs_allocated = (trans != NULL || icase); |
pstr->mbs_allocated = (trans != NULL || icase); |
173 |
pstr->mb_cur_max = dfa->mb_cur_max; |
pstr->mb_cur_max = dfa->mb_cur_max; |
174 |
pstr->is_utf8 = dfa->is_utf8; |
pstr->is_utf8 = dfa->is_utf8; |
191 |
built and starts from PSTR->VALID_LEN. */ |
built and starts from PSTR->VALID_LEN. */ |
192 |
|
|
193 |
static void |
static void |
194 |
build_wcs_buffer (pstr) |
internal_function |
195 |
re_string_t *pstr; |
build_wcs_buffer (re_string_t *pstr) |
196 |
{ |
{ |
197 |
#ifdef _LIBC |
#ifdef _LIBC |
198 |
unsigned char buf[MB_LEN_MAX]; |
unsigned char buf[MB_LEN_MAX]; |
201 |
unsigned char buf[64]; |
unsigned char buf[64]; |
202 |
#endif |
#endif |
203 |
mbstate_t prev_st; |
mbstate_t prev_st; |
204 |
int byte_idx, end_idx, remain_len; |
Idx byte_idx, end_idx, remain_len; |
205 |
size_t mbclen; |
size_t mbclen; |
206 |
|
|
207 |
/* Build the buffers from pstr->valid_len to either pstr->len or |
/* Build the buffers from pstr->valid_len to either pstr->len or |
258 |
/* Build wide character buffer PSTR->WCS like build_wcs_buffer, |
/* Build wide character buffer PSTR->WCS like build_wcs_buffer, |
259 |
but for REG_ICASE. */ |
but for REG_ICASE. */ |
260 |
|
|
261 |
static int |
static reg_errcode_t |
262 |
build_wcs_upper_buffer (pstr) |
internal_function |
263 |
re_string_t *pstr; |
build_wcs_upper_buffer (re_string_t *pstr) |
264 |
{ |
{ |
265 |
mbstate_t prev_st; |
mbstate_t prev_st; |
266 |
int src_idx, byte_idx, end_idx, remain_len; |
Idx src_idx, byte_idx, end_idx, remain_len; |
267 |
size_t mbclen; |
size_t mbclen; |
268 |
#ifdef _LIBC |
#ifdef _LIBC |
269 |
char buf[MB_LEN_MAX]; |
char buf[MB_LEN_MAX]; |
301 |
mbclen = mbrtowc (&wc, |
mbclen = mbrtowc (&wc, |
302 |
((const char *) pstr->raw_mbs + pstr->raw_mbs_idx |
((const char *) pstr->raw_mbs + pstr->raw_mbs_idx |
303 |
+ byte_idx), remain_len, &pstr->cur_state); |
+ byte_idx), remain_len, &pstr->cur_state); |
304 |
if (BE (mbclen + 2 > 2, 1)) |
if (BE ((size_t) (mbclen + 2) > 2, 1)) |
305 |
{ |
{ |
306 |
wchar_t wcu = wc; |
wchar_t wcu = wc; |
307 |
if (iswlower (wc)) |
if (iswlower (wc)) |
369 |
else |
else |
370 |
p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; |
p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; |
371 |
mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state); |
mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state); |
372 |
if (BE (mbclen + 2 > 2, 1)) |
if (BE ((size_t) (mbclen + 2) > 2, 1)) |
373 |
{ |
{ |
374 |
wchar_t wcu = wc; |
wchar_t wcu = wc; |
375 |
if (iswlower (wc)) |
if (iswlower (wc)) |
392 |
|
|
393 |
if (pstr->offsets == NULL) |
if (pstr->offsets == NULL) |
394 |
{ |
{ |
395 |
pstr->offsets = re_malloc (int, pstr->bufs_len); |
pstr->offsets = re_xmalloc (Idx, pstr->bufs_len); |
396 |
|
|
397 |
if (pstr->offsets == NULL) |
if (pstr->offsets == NULL) |
398 |
return REG_ESPACE; |
return REG_ESPACE; |
474 |
/* Skip characters until the index becomes greater than NEW_RAW_IDX. |
/* Skip characters until the index becomes greater than NEW_RAW_IDX. |
475 |
Return the index. */ |
Return the index. */ |
476 |
|
|
477 |
static int |
static Idx |
478 |
re_string_skip_chars (pstr, new_raw_idx, last_wc) |
internal_function |
479 |
re_string_t *pstr; |
re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) |
|
int new_raw_idx; |
|
|
wint_t *last_wc; |
|
480 |
{ |
{ |
481 |
mbstate_t prev_st; |
mbstate_t prev_st; |
482 |
int rawbuf_idx; |
Idx rawbuf_idx; |
483 |
size_t mbclen; |
size_t mbclen; |
484 |
wchar_t wc = 0; |
wchar_t wc = 0; |
485 |
|
|
487 |
for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; |
for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; |
488 |
rawbuf_idx < new_raw_idx;) |
rawbuf_idx < new_raw_idx;) |
489 |
{ |
{ |
490 |
int remain_len; |
Idx remain_len; |
491 |
remain_len = pstr->len - rawbuf_idx; |
remain_len = pstr->len - rawbuf_idx; |
492 |
prev_st = pstr->cur_state; |
prev_st = pstr->cur_state; |
493 |
mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx, |
mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx, |
510 |
This function is used in case of REG_ICASE. */ |
This function is used in case of REG_ICASE. */ |
511 |
|
|
512 |
static void |
static void |
513 |
build_upper_buffer (pstr) |
internal_function |
514 |
re_string_t *pstr; |
build_upper_buffer (re_string_t *pstr) |
515 |
{ |
{ |
516 |
int char_idx, end_idx; |
Idx char_idx, end_idx; |
517 |
end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; |
end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; |
518 |
|
|
519 |
for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) |
for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) |
533 |
/* Apply TRANS to the buffer in PSTR. */ |
/* Apply TRANS to the buffer in PSTR. */ |
534 |
|
|
535 |
static void |
static void |
536 |
re_string_translate_buffer (pstr) |
internal_function |
537 |
re_string_t *pstr; |
re_string_translate_buffer (re_string_t *pstr) |
538 |
{ |
{ |
539 |
int buf_idx, end_idx; |
Idx buf_idx, end_idx; |
540 |
end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; |
end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; |
541 |
|
|
542 |
for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) |
for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) |
554 |
convert to upper case in case of REG_ICASE, apply translation. */ |
convert to upper case in case of REG_ICASE, apply translation. */ |
555 |
|
|
556 |
static reg_errcode_t |
static reg_errcode_t |
557 |
re_string_reconstruct (pstr, idx, eflags) |
internal_function |
558 |
re_string_t *pstr; |
re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) |
|
int idx, eflags; |
|
559 |
{ |
{ |
560 |
int offset = idx - pstr->raw_mbs_idx; |
Idx offset; |
561 |
if (BE (offset < 0, 0)) |
|
562 |
|
if (BE (pstr->raw_mbs_idx <= idx, 0)) |
563 |
|
offset = idx - pstr->raw_mbs_idx; |
564 |
|
else |
565 |
{ |
{ |
566 |
/* Reset buffer. */ |
/* Reset buffer. */ |
567 |
#ifdef RE_ENABLE_I18N |
#ifdef RE_ENABLE_I18N |
624 |
#ifdef RE_ENABLE_I18N |
#ifdef RE_ENABLE_I18N |
625 |
if (pstr->mb_cur_max > 1) |
if (pstr->mb_cur_max > 1) |
626 |
{ |
{ |
627 |
int wcs_idx; |
Idx wcs_idx; |
628 |
wint_t wc = WEOF; |
wint_t wc = WEOF; |
629 |
|
|
630 |
if (pstr->is_utf8) |
if (pstr->is_utf8) |
640 |
{ |
{ |
641 |
mbstate_t cur_state; |
mbstate_t cur_state; |
642 |
wchar_t wc2; |
wchar_t wc2; |
643 |
int mlen = raw + pstr->len - p; |
Idx mlen = raw + pstr->len - p; |
644 |
unsigned char buf[6]; |
unsigned char buf[6]; |
645 |
|
size_t mbclen; |
646 |
|
|
647 |
q = p; |
q = p; |
648 |
if (BE (pstr->trans != NULL, 0)) |
if (BE (pstr->trans != NULL, 0)) |
655 |
/* XXX Don't use mbrtowc, we know which conversion |
/* XXX Don't use mbrtowc, we know which conversion |
656 |
to use (UTF-8 -> UCS4). */ |
to use (UTF-8 -> UCS4). */ |
657 |
memset (&cur_state, 0, sizeof (cur_state)); |
memset (&cur_state, 0, sizeof (cur_state)); |
658 |
mlen = (mbrtowc (&wc2, (const char *) p, mlen, |
mbclen = mbrtowc (&wc2, (const char *) p, mlen, |
659 |
&cur_state) |
&cur_state); |
660 |
- (raw + offset - p)); |
if (raw + offset - p <= mbclen && mbclen < (size_t) -2) |
|
if (mlen >= 0) |
|
661 |
{ |
{ |
662 |
memset (&pstr->cur_state, '\0', |
memset (&pstr->cur_state, '\0', |
663 |
sizeof (mbstate_t)); |
sizeof (mbstate_t)); |
664 |
pstr->valid_len = mlen; |
pstr->valid_len = mbclen - (raw + offset - p); |
665 |
wc = wc2; |
wc = wc2; |
666 |
} |
} |
667 |
break; |
break; |
675 |
for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) |
for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) |
676 |
pstr->wcs[wcs_idx] = WEOF; |
pstr->wcs[wcs_idx] = WEOF; |
677 |
if (pstr->mbs_allocated) |
if (pstr->mbs_allocated) |
678 |
memset (pstr->mbs, 255, pstr->valid_len); |
memset (pstr->mbs, -1, pstr->valid_len); |
679 |
} |
} |
680 |
pstr->valid_raw_len = pstr->valid_len; |
pstr->valid_raw_len = pstr->valid_len; |
681 |
pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) |
pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) |
710 |
{ |
{ |
711 |
if (pstr->icase) |
if (pstr->icase) |
712 |
{ |
{ |
713 |
int ret = build_wcs_upper_buffer (pstr); |
reg_errcode_t ret = build_wcs_upper_buffer (pstr); |
714 |
if (BE (ret != REG_NOERROR, 0)) |
if (BE (ret != REG_NOERROR, 0)) |
715 |
return ret; |
return ret; |
716 |
} |
} |
734 |
} |
} |
735 |
|
|
736 |
static unsigned char |
static unsigned char |
737 |
re_string_peek_byte_case (pstr, idx) |
internal_function __attribute ((pure)) |
738 |
const re_string_t *pstr; |
re_string_peek_byte_case (const re_string_t *pstr, Idx idx) |
|
int idx; |
|
739 |
{ |
{ |
740 |
int ch, off; |
int ch; |
741 |
|
Idx off; |
742 |
|
|
743 |
/* Handle the common (easiest) cases first. */ |
/* Handle the common (easiest) cases first. */ |
744 |
if (BE (!pstr->mbs_allocated, 1)) |
if (BE (!pstr->mbs_allocated, 1)) |
771 |
} |
} |
772 |
|
|
773 |
static unsigned char |
static unsigned char |
774 |
re_string_fetch_byte_case (pstr) |
internal_function __attribute ((pure)) |
775 |
re_string_t *pstr; |
re_string_fetch_byte_case (re_string_t *pstr) |
776 |
{ |
{ |
777 |
if (BE (!pstr->mbs_allocated, 1)) |
if (BE (!pstr->mbs_allocated, 1)) |
778 |
return re_string_fetch_byte (pstr); |
return re_string_fetch_byte (pstr); |
780 |
#ifdef RE_ENABLE_I18N |
#ifdef RE_ENABLE_I18N |
781 |
if (pstr->offsets_needed) |
if (pstr->offsets_needed) |
782 |
{ |
{ |
783 |
int off, ch; |
Idx off; |
784 |
|
int ch; |
785 |
|
|
786 |
/* For tr_TR.UTF-8 [[:islower:]] there is |
/* For tr_TR.UTF-8 [[:islower:]] there is |
787 |
[[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip |
[[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip |
809 |
} |
} |
810 |
|
|
811 |
static void |
static void |
812 |
re_string_destruct (pstr) |
internal_function |
813 |
re_string_t *pstr; |
re_string_destruct (re_string_t *pstr) |
814 |
{ |
{ |
815 |
#ifdef RE_ENABLE_I18N |
#ifdef RE_ENABLE_I18N |
816 |
re_free (pstr->wcs); |
re_free (pstr->wcs); |
823 |
/* Return the context at IDX in INPUT. */ |
/* Return the context at IDX in INPUT. */ |
824 |
|
|
825 |
static unsigned int |
static unsigned int |
826 |
re_string_context_at (input, idx, eflags) |
internal_function |
827 |
const re_string_t *input; |
re_string_context_at (const re_string_t *input, Idx idx, int eflags) |
|
int idx, eflags; |
|
828 |
{ |
{ |
829 |
int c; |
int c; |
830 |
if (BE (idx < 0, 0)) |
if (BE (! REG_VALID_INDEX (idx), 0)) |
831 |
/* In this case, we use the value stored in input->tip_context, |
/* In this case, we use the value stored in input->tip_context, |
832 |
since we can't know the character in input->mbs[-1] here. */ |
since we can't know the character in input->mbs[-1] here. */ |
833 |
return input->tip_context; |
return input->tip_context; |
838 |
if (input->mb_cur_max > 1) |
if (input->mb_cur_max > 1) |
839 |
{ |
{ |
840 |
wint_t wc; |
wint_t wc; |
841 |
int wc_idx = idx; |
Idx wc_idx = idx; |
842 |
while(input->wcs[wc_idx] == WEOF) |
while(input->wcs[wc_idx] == WEOF) |
843 |
{ |
{ |
844 |
#ifdef DEBUG |
#ifdef DEBUG |
845 |
/* It must not happen. */ |
/* It must not happen. */ |
846 |
assert (wc_idx >= 0); |
assert (REG_VALID_INDEX (wc_idx)); |
847 |
#endif |
#endif |
848 |
--wc_idx; |
--wc_idx; |
849 |
if (wc_idx < 0) |
if (! REG_VALID_INDEX (wc_idx)) |
850 |
return input->tip_context; |
return input->tip_context; |
851 |
} |
} |
852 |
wc = input->wcs[wc_idx]; |
wc = input->wcs[wc_idx]; |
868 |
/* Functions for set operation. */ |
/* Functions for set operation. */ |
869 |
|
|
870 |
static reg_errcode_t |
static reg_errcode_t |
871 |
re_node_set_alloc (set, size) |
internal_function |
872 |
re_node_set *set; |
re_node_set_alloc (re_node_set *set, Idx size) |
|
int size; |
|
873 |
{ |
{ |
874 |
set->alloc = size; |
set->alloc = size; |
875 |
set->nelem = 0; |
set->nelem = 0; |
876 |
set->elems = re_malloc (int, size); |
set->elems = re_xmalloc (Idx, size); |
877 |
if (BE (set->elems == NULL, 0)) |
if (BE (set->elems == NULL, 0)) |
878 |
return REG_ESPACE; |
return REG_ESPACE; |
879 |
return REG_NOERROR; |
return REG_NOERROR; |
880 |
} |
} |
881 |
|
|
882 |
static reg_errcode_t |
static reg_errcode_t |
883 |
re_node_set_init_1 (set, elem) |
internal_function |
884 |
re_node_set *set; |
re_node_set_init_1 (re_node_set *set, Idx elem) |
|
int elem; |
|
885 |
{ |
{ |
886 |
set->alloc = 1; |
set->alloc = 1; |
887 |
set->nelem = 1; |
set->nelem = 1; |
888 |
set->elems = re_malloc (int, 1); |
set->elems = re_malloc (Idx, 1); |
889 |
if (BE (set->elems == NULL, 0)) |
if (BE (set->elems == NULL, 0)) |
890 |
{ |
{ |
891 |
set->alloc = set->nelem = 0; |
set->alloc = set->nelem = 0; |
896 |
} |
} |
897 |
|
|
898 |
static reg_errcode_t |
static reg_errcode_t |
899 |
re_node_set_init_2 (set, elem1, elem2) |
internal_function |
900 |
re_node_set *set; |
re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) |
|
int elem1, elem2; |
|
901 |
{ |
{ |
902 |
set->alloc = 2; |
set->alloc = 2; |
903 |
set->elems = re_malloc (int, 2); |
set->elems = re_malloc (Idx, 2); |
904 |
if (BE (set->elems == NULL, 0)) |
if (BE (set->elems == NULL, 0)) |
905 |
return REG_ESPACE; |
return REG_ESPACE; |
906 |
if (elem1 == elem2) |
if (elem1 == elem2) |
926 |
} |
} |
927 |
|
|
928 |
static reg_errcode_t |
static reg_errcode_t |
929 |
re_node_set_init_copy (dest, src) |
internal_function |
930 |
re_node_set *dest; |
re_node_set_init_copy (re_node_set *dest, const re_node_set *src) |
|
const re_node_set *src; |
|
931 |
{ |
{ |
932 |
dest->nelem = src->nelem; |
dest->nelem = src->nelem; |
933 |
if (src->nelem > 0) |
if (src->nelem > 0) |
934 |
{ |
{ |
935 |
dest->alloc = dest->nelem; |
dest->alloc = dest->nelem; |
936 |
dest->elems = re_malloc (int, dest->alloc); |
dest->elems = re_malloc (Idx, dest->alloc); |
937 |
if (BE (dest->elems == NULL, 0)) |
if (BE (dest->elems == NULL, 0)) |
938 |
{ |
{ |
939 |
dest->alloc = dest->nelem = 0; |
dest->alloc = dest->nelem = 0; |
940 |
return REG_ESPACE; |
return REG_ESPACE; |
941 |
} |
} |
942 |
memcpy (dest->elems, src->elems, src->nelem * sizeof (int)); |
memcpy (dest->elems, src->elems, src->nelem * sizeof dest->elems[0]); |
943 |
} |
} |
944 |
else |
else |
945 |
re_node_set_init_empty (dest); |
re_node_set_init_empty (dest); |
951 |
Note: We assume dest->elems is NULL, when dest->alloc is 0. */ |
Note: We assume dest->elems is NULL, when dest->alloc is 0. */ |
952 |
|
|
953 |
static reg_errcode_t |
static reg_errcode_t |
954 |
re_node_set_add_intersect (dest, src1, src2) |
internal_function |
955 |
re_node_set *dest; |
re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, |
956 |
const re_node_set *src1, *src2; |
const re_node_set *src2) |
957 |
{ |
{ |
958 |
int i1, i2, is, id, delta, sbase; |
Idx i1, i2, is, id, delta, sbase; |
959 |
if (src1->nelem == 0 || src2->nelem == 0) |
if (src1->nelem == 0 || src2->nelem == 0) |
960 |
return REG_NOERROR; |
return REG_NOERROR; |
961 |
|
|
963 |
conservative estimate. */ |
conservative estimate. */ |
964 |
if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) |
if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) |
965 |
{ |
{ |
966 |
int new_alloc = src1->nelem + src2->nelem + dest->alloc; |
Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; |
967 |
int *new_elems = re_realloc (dest->elems, int, new_alloc); |
Idx *new_elems; |
968 |
|
if (sizeof (Idx) < 3 |
969 |
|
&& (new_alloc < dest->alloc |
970 |
|
|| ((Idx) (src1->nelem + src2->nelem) < src1->nelem))) |
971 |
|
return REG_ESPACE; |
972 |
|
new_elems = re_xrealloc (dest->elems, Idx, new_alloc); |
973 |
if (BE (new_elems == NULL, 0)) |
if (BE (new_elems == NULL, 0)) |
974 |
return REG_ESPACE; |
return REG_ESPACE; |
975 |
dest->elems = new_elems; |
dest->elems = new_elems; |
987 |
if (src1->elems[i1] == src2->elems[i2]) |
if (src1->elems[i1] == src2->elems[i2]) |
988 |
{ |
{ |
989 |
/* Try to find the item in DEST. Maybe we could binary search? */ |
/* Try to find the item in DEST. Maybe we could binary search? */ |
990 |
while (id >= 0 && dest->elems[id] > src1->elems[i1]) |
while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) |
991 |
--id; |
--id; |
992 |
|
|
993 |
if (id < 0 || dest->elems[id] != src1->elems[i1]) |
if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) |
994 |
dest->elems[--sbase] = src1->elems[i1]; |
dest->elems[--sbase] = src1->elems[i1]; |
995 |
|
|
996 |
if (--i1 < 0 || --i2 < 0) |
if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) |
997 |
break; |
break; |
998 |
} |
} |
999 |
|
|
1000 |
/* Lower the highest of the two items. */ |
/* Lower the highest of the two items. */ |
1001 |
else if (src1->elems[i1] < src2->elems[i2]) |
else if (src1->elems[i1] < src2->elems[i2]) |
1002 |
{ |
{ |
1003 |
if (--i2 < 0) |
if (! REG_VALID_INDEX (--i2)) |
1004 |
break; |
break; |
1005 |
} |
} |
1006 |
else |
else |
1007 |
{ |
{ |
1008 |
if (--i1 < 0) |
if (! REG_VALID_INDEX (--i1)) |
1009 |
break; |
break; |
1010 |
} |
} |
1011 |
} |
} |
1018 |
DEST elements are already in place; this is more or |
DEST elements are already in place; this is more or |
1019 |
less the same loop that is in re_node_set_merge. */ |
less the same loop that is in re_node_set_merge. */ |
1020 |
dest->nelem += delta; |
dest->nelem += delta; |
1021 |
if (delta > 0 && id >= 0) |
if (delta > 0 && REG_VALID_INDEX (id)) |
1022 |
for (;;) |
for (;;) |
1023 |
{ |
{ |
1024 |
if (dest->elems[is] > dest->elems[id]) |
if (dest->elems[is] > dest->elems[id]) |
1032 |
{ |
{ |
1033 |
/* Slide from the bottom. */ |
/* Slide from the bottom. */ |
1034 |
dest->elems[id + delta] = dest->elems[id]; |
dest->elems[id + delta] = dest->elems[id]; |
1035 |
if (--id < 0) |
if (! REG_VALID_INDEX (--id)) |
1036 |
break; |
break; |
1037 |
} |
} |
1038 |
} |
} |
1039 |
|
|
1040 |
/* Copy remaining SRC elements. */ |
/* Copy remaining SRC elements. */ |
1041 |
memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int)); |
memcpy (dest->elems, dest->elems + sbase, delta * sizeof dest->elems[0]); |
1042 |
|
|
1043 |
return REG_NOERROR; |
return REG_NOERROR; |
1044 |
} |
} |
1047 |
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ |
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ |
1048 |
|
|
1049 |
static reg_errcode_t |
static reg_errcode_t |
1050 |
re_node_set_init_union (dest, src1, src2) |
internal_function |
1051 |
re_node_set *dest; |
re_node_set_init_union (re_node_set *dest, const re_node_set *src1, |
1052 |
const re_node_set *src1, *src2; |
const re_node_set *src2) |
1053 |
{ |
{ |
1054 |
int i1, i2, id; |
Idx i1, i2, id; |
1055 |
if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) |
if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) |
1056 |
{ |
{ |
1057 |
dest->alloc = src1->nelem + src2->nelem; |
dest->alloc = src1->nelem + src2->nelem; |
1058 |
dest->elems = re_malloc (int, dest->alloc); |
if (sizeof (Idx) < 2 && dest->alloc < src1->nelem) |
1059 |
|
return REG_ESPACE; |
1060 |
|
dest->elems = re_xmalloc (Idx, dest->alloc); |
1061 |
if (BE (dest->elems == NULL, 0)) |
if (BE (dest->elems == NULL, 0)) |
1062 |
return REG_ESPACE; |
return REG_ESPACE; |
1063 |
} |
} |
1085 |
if (i1 < src1->nelem) |
if (i1 < src1->nelem) |
1086 |
{ |
{ |
1087 |
memcpy (dest->elems + id, src1->elems + i1, |
memcpy (dest->elems + id, src1->elems + i1, |
1088 |
(src1->nelem - i1) * sizeof (int)); |
(src1->nelem - i1) * sizeof dest->elems[0]); |
1089 |
id += src1->nelem - i1; |
id += src1->nelem - i1; |
1090 |
} |
} |
1091 |
else if (i2 < src2->nelem) |
else if (i2 < src2->nelem) |
1092 |
{ |
{ |
1093 |
memcpy (dest->elems + id, src2->elems + i2, |
memcpy (dest->elems + id, src2->elems + i2, |
1094 |
(src2->nelem - i2) * sizeof (int)); |
(src2->nelem - i2) * sizeof dest->elems[0]); |
1095 |
id += src2->nelem - i2; |
id += src2->nelem - i2; |
1096 |
} |
} |
1097 |
dest->nelem = id; |
dest->nelem = id; |
1102 |
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ |
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ |
1103 |
|
|
1104 |
static reg_errcode_t |
static reg_errcode_t |
1105 |
re_node_set_merge (dest, src) |
internal_function |
1106 |
re_node_set *dest; |
re_node_set_merge (re_node_set *dest, const re_node_set *src) |
|
const re_node_set *src; |
|
1107 |
{ |
{ |
1108 |
int is, id, sbase, delta; |
Idx is, id, sbase, delta; |
1109 |
if (src == NULL || src->nelem == 0) |
if (src == NULL || src->nelem == 0) |
1110 |
return REG_NOERROR; |
return REG_NOERROR; |
1111 |
|
if (sizeof (Idx) < 3 |
1112 |
|
&& ((Idx) (2 * src->nelem) < src->nelem |
1113 |
|
|| (Idx) (2 * src->nelem + dest->nelem) < dest->nelem)) |
1114 |
|
return REG_ESPACE; |
1115 |
if (dest->alloc < 2 * src->nelem + dest->nelem) |
if (dest->alloc < 2 * src->nelem + dest->nelem) |
1116 |
{ |
{ |
1117 |
int new_alloc = 2 * (src->nelem + dest->alloc); |
Idx new_alloc = src->nelem + dest->alloc; |
1118 |
int *new_buffer = re_realloc (dest->elems, int, new_alloc); |
Idx *new_buffer; |
1119 |
|
if (sizeof (Idx) < 4 && new_alloc < dest->alloc) |
1120 |
|
return REG_ESPACE; |
1121 |
|
new_buffer = re_x2realloc (dest->elems, Idx, &new_alloc); |
1122 |
if (BE (new_buffer == NULL, 0)) |
if (BE (new_buffer == NULL, 0)) |
1123 |
return REG_ESPACE; |
return REG_ESPACE; |
1124 |
dest->elems = new_buffer; |
dest->elems = new_buffer; |
1128 |
if (BE (dest->nelem == 0, 0)) |
if (BE (dest->nelem == 0, 0)) |
1129 |
{ |
{ |
1130 |
dest->nelem = src->nelem; |
dest->nelem = src->nelem; |
1131 |
memcpy (dest->elems, src->elems, src->nelem * sizeof (int)); |
memcpy (dest->elems, src->elems, src->nelem * sizeof dest->elems[0]); |
1132 |
return REG_NOERROR; |
return REG_NOERROR; |
1133 |
} |
} |
1134 |
|
|
1135 |
/* Copy into the top of DEST the items of SRC that are not |
/* Copy into the top of DEST the items of SRC that are not |
1136 |
found in DEST. Maybe we could binary search in DEST? */ |
found in DEST. Maybe we could binary search in DEST? */ |
1137 |
for (sbase = dest->nelem + 2 * src->nelem, |
for (sbase = dest->nelem + 2 * src->nelem, |
1138 |
is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; ) |
is = src->nelem - 1, id = dest->nelem - 1; |
1139 |
|
REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) |
1140 |
{ |
{ |
1141 |
if (dest->elems[id] == src->elems[is]) |
if (dest->elems[id] == src->elems[is]) |
1142 |
is--, id--; |
is--, id--; |
1146 |
--id; |
--id; |
1147 |
} |
} |
1148 |
|
|
1149 |
if (is >= 0) |
if (REG_VALID_INDEX (is)) |
1150 |
{ |
{ |
1151 |
/* If DEST is exhausted, the remaining items of SRC must be unique. */ |
/* If DEST is exhausted, the remaining items of SRC must be unique. */ |
1152 |
sbase -= is + 1; |
sbase -= is + 1; |
1153 |
memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int)); |
memcpy (dest->elems + sbase, src->elems, |
1154 |
|
(is + 1) * sizeof dest->elems[0]); |
1155 |
} |
} |
1156 |
|
|
1157 |
id = dest->nelem - 1; |
id = dest->nelem - 1; |
1176 |
{ |
{ |
1177 |
/* Slide from the bottom. */ |
/* Slide from the bottom. */ |
1178 |
dest->elems[id + delta] = dest->elems[id]; |
dest->elems[id + delta] = dest->elems[id]; |
1179 |
if (--id < 0) |
if (! REG_VALID_INDEX (--id)) |
1180 |
{ |
{ |
1181 |
/* Copy remaining SRC elements. */ |
/* Copy remaining SRC elements. */ |
1182 |
memcpy (dest->elems, dest->elems + sbase, |
memcpy (dest->elems, dest->elems + sbase, |
1183 |
delta * sizeof (int)); |
delta * sizeof dest->elems[0]); |
1184 |
break; |
break; |
1185 |
} |
} |
1186 |
} |
} |
1191 |
|
|
1192 |
/* Insert the new element ELEM to the re_node_set* SET. |
/* Insert the new element ELEM to the re_node_set* SET. |
1193 |
SET should not already have ELEM. |
SET should not already have ELEM. |
1194 |
return -1 if an error is occured, return 1 otherwise. */ |
Return true if successful. */ |
1195 |
|
|
1196 |
static int |
static bool |
1197 |
re_node_set_insert (set, elem) |
internal_function |
1198 |
re_node_set *set; |
re_node_set_insert (re_node_set *set, Idx elem) |
|
int elem; |
|
1199 |
{ |
{ |
1200 |
int idx; |
Idx idx; |
1201 |
/* In case the set is empty. */ |
/* In case the set is empty. */ |
1202 |
if (set->alloc == 0) |
if (set->alloc == 0) |
1203 |
{ |
return re_node_set_init_1 (set, elem) == REG_NOERROR; |
|
if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1)) |
|
|
return 1; |
|
|
else |
|
|
return -1; |
|
|
} |
|
1204 |
|
|
1205 |
if (BE (set->nelem, 0) == 0) |
if (BE (set->nelem, 0) == 0) |
1206 |
{ |
{ |
1207 |
/* We already guaranteed above that set->alloc != 0. */ |
/* We already guaranteed above that set->alloc != 0. */ |
1208 |
set->elems[0] = elem; |
set->elems[0] = elem; |
1209 |
++set->nelem; |
++set->nelem; |
1210 |
return 1; |
return true; |
1211 |
} |
} |
1212 |
|
|
1213 |
/* Realloc if we need. */ |
/* Realloc if we need. */ |
1214 |
if (set->alloc == set->nelem) |
if (set->alloc == set->nelem) |
1215 |
{ |
{ |
1216 |
int *new_array; |
Idx *new_elems = re_x2realloc (set->elems, Idx, &set->alloc); |
1217 |
set->alloc = set->alloc * 2; |
if (BE (new_elems == NULL, 0)) |
1218 |
new_array = re_realloc (set->elems, int, set->alloc); |
return false; |
1219 |
if (BE (new_array == NULL, 0)) |
set->elems = new_elems; |
|
return -1; |
|
|
set->elems = new_array; |
|
1220 |
} |
} |
1221 |
|
|
1222 |
/* Move the elements which follows the new element. Test the |
/* Move the elements which follows the new element. Test the |
1236 |
/* Insert the new element. */ |
/* Insert the new element. */ |
1237 |
set->elems[idx] = elem; |
set->elems[idx] = elem; |
1238 |
++set->nelem; |
++set->nelem; |
1239 |
return 1; |
return true; |
1240 |
} |
} |
1241 |
|
|
1242 |
/* Insert the new element ELEM to the re_node_set* SET. |
/* Insert the new element ELEM to the re_node_set* SET. |
1243 |
SET should not already have any element greater than or equal to ELEM. |
SET should not already have any element greater than or equal to ELEM. |
1244 |
Return -1 if an error is occured, return 1 otherwise. */ |
Return true if successful. */ |
1245 |
|
|
1246 |
static int |
static bool |
1247 |
re_node_set_insert_last (set, elem) |
internal_function |
1248 |
re_node_set *set; |
re_node_set_insert_last (re_node_set *set, Idx elem) |
|
int elem; |
|
1249 |
{ |
{ |
1250 |
/* Realloc if we need. */ |
/* Realloc if we need. */ |
1251 |
if (set->alloc == set->nelem) |
if (set->alloc == set->nelem) |
1252 |
{ |
{ |
1253 |
int *new_array; |
Idx *new_elems; |
1254 |
set->alloc = (set->alloc + 1) * 2; |
new_elems = re_x2realloc (set->elems, Idx, &set->alloc); |
1255 |
new_array = re_realloc (set->elems, int, set->alloc); |
if (BE (new_elems == NULL, 0)) |
1256 |
if (BE (new_array == NULL, 0)) |
return false; |
1257 |
return -1; |
set->elems = new_elems; |
|
set->elems = new_array; |
|
1258 |
} |
} |
1259 |
|
|
1260 |
/* Insert the new element. */ |
/* Insert the new element. */ |
1261 |
set->elems[set->nelem++] = elem; |
set->elems[set->nelem++] = elem; |
1262 |
return 1; |
return true; |
1263 |
} |
} |
1264 |
|
|
1265 |
/* Compare two node sets SET1 and SET2. |
/* Compare two node sets SET1 and SET2. |
1266 |
return 1 if SET1 and SET2 are equivalent, return 0 otherwise. */ |
Return true if SET1 and SET2 are equivalent. */ |
1267 |
|
|
1268 |
static int |
static bool |
1269 |
re_node_set_compare (set1, set2) |
internal_function __attribute ((pure)) |
1270 |
const re_node_set *set1, *set2; |
re_node_set_compare (const re_node_set *set1, const re_node_set *set2) |
1271 |
{ |
{ |
1272 |
int i; |
Idx i; |
1273 |
if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) |
if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) |
1274 |
return 0; |
return false; |
1275 |
for (i = set1->nelem ; --i >= 0 ; ) |
for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) |
1276 |
if (set1->elems[i] != set2->elems[i]) |
if (set1->elems[i] != set2->elems[i]) |
1277 |
return 0; |
return false; |
1278 |
return 1; |
return true; |
1279 |
} |
} |
1280 |
|
|
1281 |
/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ |
/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ |
1282 |
|
|
1283 |
static int |
static Idx |
1284 |
re_node_set_contains (set, elem) |
internal_function __attribute ((pure)) |
1285 |
const re_node_set *set; |
re_node_set_contains (const re_node_set *set, Idx elem) |
|
int elem; |
|
1286 |
{ |
{ |
1287 |
unsigned int idx, right, mid; |
__re_size_t idx, right, mid; |
1288 |
if (set->nelem <= 0) |
if (! REG_VALID_NONZERO_INDEX (set->nelem)) |
1289 |
return 0; |
return 0; |
1290 |
|
|
1291 |
/* Binary search the element. */ |
/* Binary search the element. */ |
1303 |
} |
} |
1304 |
|
|
1305 |
static void |
static void |
1306 |
re_node_set_remove_at (set, idx) |
internal_function |
1307 |
re_node_set *set; |
re_node_set_remove_at (re_node_set *set, Idx idx) |
|
int idx; |
|
1308 |
{ |
{ |
1309 |
if (idx < 0 || idx >= set->nelem) |
if (idx < 0 || idx >= set->nelem) |
1310 |
return; |
return; |
1315 |
|
|
1316 |
|
|
1317 |
/* Add the token TOKEN to dfa->nodes, and return the index of the token. |
/* Add the token TOKEN to dfa->nodes, and return the index of the token. |
1318 |
Or return -1, if an error will be occured. */ |
Or return REG_MISSING if an error occurred. */ |
1319 |
|
|
1320 |
static int |
static Idx |
1321 |
re_dfa_add_node (dfa, token) |
internal_function |
1322 |
re_dfa_t *dfa; |
re_dfa_add_node (re_dfa_t *dfa, re_token_t token) |
|
re_token_t token; |
|
1323 |
{ |
{ |
1324 |
int type = token.type; |
int type = token.type; |
1325 |
if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) |
if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) |
1326 |
{ |
{ |
1327 |
int new_nodes_alloc = dfa->nodes_alloc * 2; |
Idx new_nodes_alloc = dfa->nodes_alloc; |
1328 |
int *new_nexts, *new_indices; |
Idx *new_nexts, *new_indices; |
1329 |
re_node_set *new_edests, *new_eclosures; |
re_node_set *new_edests, *new_eclosures; |
1330 |
|
|
1331 |
re_token_t *new_array = re_realloc (dfa->nodes, re_token_t, |
re_token_t *new_nodes = re_x2realloc (dfa->nodes, re_token_t, |
1332 |
new_nodes_alloc); |
&new_nodes_alloc); |
1333 |
if (BE (new_array == NULL, 0)) |
if (BE (new_nodes == NULL, 0)) |
1334 |
return -1; |
return REG_MISSING; |
1335 |
dfa->nodes = new_array; |
dfa->nodes = new_nodes; |
1336 |
new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc); |
new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); |
1337 |
new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc); |
new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); |
1338 |
new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); |
new_edests = re_xrealloc (dfa->edests, re_node_set, new_nodes_alloc); |
1339 |
new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); |
new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); |
1340 |
if (BE (new_nexts == NULL || new_indices == NULL |
if (BE (new_nexts == NULL || new_indices == NULL |
1341 |
|| new_edests == NULL || new_eclosures == NULL, 0)) |
|| new_edests == NULL || new_eclosures == NULL, 0)) |
1342 |
return -1; |
return REG_MISSING; |
1343 |
dfa->nexts = new_nexts; |
dfa->nexts = new_nexts; |
1344 |
dfa->org_indices = new_indices; |
dfa->org_indices = new_indices; |
1345 |
dfa->edests = new_edests; |
dfa->edests = new_edests; |
1352 |
dfa->nodes[dfa->nodes_len].accept_mb = |
dfa->nodes[dfa->nodes_len].accept_mb = |
1353 |
(type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET; |
(type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET; |
1354 |
#endif |
#endif |
1355 |
dfa->nexts[dfa->nodes_len] = -1; |
dfa->nexts[dfa->nodes_len] = REG_MISSING; |
1356 |
re_node_set_init_empty (dfa->edests + dfa->nodes_len); |
re_node_set_init_empty (dfa->edests + dfa->nodes_len); |
1357 |
re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); |
re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); |
1358 |
return dfa->nodes_len++; |
return dfa->nodes_len++; |
1359 |
} |
} |
1360 |
|
|
1361 |
static unsigned int inline |
static inline re_hashval_t |
1362 |
calc_state_hash (nodes, context) |
internal_function |
1363 |
const re_node_set *nodes; |
calc_state_hash (const re_node_set *nodes, unsigned int context) |
|
unsigned int context; |
|
1364 |
{ |
{ |
1365 |
unsigned int hash = nodes->nelem + context; |
re_hashval_t hash = nodes->nelem + context; |
1366 |
int i; |
Idx i; |
1367 |
for (i = 0 ; i < nodes->nelem ; i++) |
for (i = 0 ; i < nodes->nelem ; i++) |
1368 |
hash += nodes->elems[i]; |
hash += nodes->elems[i]; |
1369 |
return hash; |
return hash; |
1379 |
optimization. */ |
optimization. */ |
1380 |
|
|
1381 |
static re_dfastate_t* |
static re_dfastate_t* |
1382 |
re_acquire_state (err, dfa, nodes) |
internal_function |
1383 |
reg_errcode_t *err; |
re_acquire_state (reg_errcode_t *err, re_dfa_t *dfa, const re_node_set *nodes) |
|
re_dfa_t *dfa; |
|
|
const re_node_set *nodes; |
|
1384 |
{ |
{ |
1385 |
unsigned int hash; |
re_hashval_t hash; |
1386 |
re_dfastate_t *new_state; |
re_dfastate_t *new_state; |
1387 |
struct re_state_table_entry *spot; |
struct re_state_table_entry *spot; |
1388 |
int i; |
Idx i; |
1389 |
|
#ifdef lint |
1390 |
|
/* Suppress bogus uninitialized-variable warnings. */ |
1391 |
|
*err = REG_NOERROR; |
1392 |
|
#endif |
1393 |
if (BE (nodes->nelem == 0, 0)) |
if (BE (nodes->nelem == 0, 0)) |
1394 |
{ |
{ |
1395 |
*err = REG_NOERROR; |
*err = REG_NOERROR; |
1429 |
optimization. */ |
optimization. */ |
1430 |
|
|
1431 |
static re_dfastate_t* |
static re_dfastate_t* |
1432 |
re_acquire_state_context (err, dfa, nodes, context) |
internal_function |
1433 |
reg_errcode_t *err; |
re_acquire_state_context (reg_errcode_t *err, re_dfa_t *dfa, |
1434 |
re_dfa_t *dfa; |
const re_node_set *nodes, unsigned int context) |
|
const re_node_set *nodes; |
|
|
unsigned int context; |
|
1435 |
{ |
{ |
1436 |
unsigned int hash; |
re_hashval_t hash; |
1437 |
re_dfastate_t *new_state; |
re_dfastate_t *new_state; |
1438 |
struct re_state_table_entry *spot; |
struct re_state_table_entry *spot; |
1439 |
int i; |
Idx i; |
1440 |
|
#ifdef lint |
1441 |
|
/* Suppress bogus uninitialized-variable warnings. */ |
1442 |
|
*err = REG_NOERROR; |
1443 |
|
#endif |
1444 |
if (nodes->nelem == 0) |
if (nodes->nelem == 0) |
1445 |
{ |
{ |
1446 |
*err = REG_NOERROR; |
*err = REG_NOERROR; |
1473 |
indicates the error code if failed. */ |
indicates the error code if failed. */ |
1474 |
|
|
1475 |
static reg_errcode_t |
static reg_errcode_t |
1476 |
register_state (dfa, newstate, hash) |
internal_function |
1477 |
re_dfa_t *dfa; |
register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, re_hashval_t hash) |
|
re_dfastate_t *newstate; |
|
|
unsigned int hash; |
|
1478 |
{ |
{ |
1479 |
struct re_state_table_entry *spot; |
struct re_state_table_entry *spot; |
1480 |
reg_errcode_t err; |
reg_errcode_t err; |
1481 |
int i; |
Idx i; |
1482 |
|
|
1483 |
newstate->hash = hash; |
newstate->hash = hash; |
1484 |
err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); |
err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); |
1486 |
return REG_ESPACE; |
return REG_ESPACE; |
1487 |
for (i = 0; i < newstate->nodes.nelem; i++) |
for (i = 0; i < newstate->nodes.nelem; i++) |
1488 |
{ |
{ |
1489 |
int elem = newstate->nodes.elems[i]; |
Idx elem = newstate->nodes.elems[i]; |
1490 |
if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) |
if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) |
1491 |
re_node_set_insert_last (&newstate->non_eps_nodes, elem); |
{ |
1492 |
|
bool ok = re_node_set_insert_last (&newstate->non_eps_nodes, elem); |
1493 |
|
if (BE (! ok, 0)) |
1494 |
|
return REG_ESPACE; |
1495 |
|
} |
1496 |
} |
} |
1497 |
|
|
1498 |
spot = dfa->state_table + (hash & dfa->state_hash_mask); |
spot = dfa->state_table + (hash & dfa->state_hash_mask); |
1499 |
if (BE (spot->alloc <= spot->num, 0)) |
if (BE (spot->alloc <= spot->num, 0)) |
1500 |
{ |
{ |
1501 |
int new_alloc = 2 * spot->num + 2; |
Idx new_alloc = spot->num; |
1502 |
re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, |
re_dfastate_t **new_array = re_x2realloc (spot->array, re_dfastate_t *, |
1503 |
new_alloc); |
&new_alloc); |
1504 |
if (BE (new_array == NULL, 0)) |
if (BE (new_array == NULL, 0)) |
1505 |
return REG_ESPACE; |
return REG_ESPACE; |
1506 |
spot->array = new_array; |
spot->array = new_array; |
1514 |
Return the new state if succeeded, otherwise return NULL. */ |
Return the new state if succeeded, otherwise return NULL. */ |
1515 |
|
|
1516 |
static re_dfastate_t * |
static re_dfastate_t * |
1517 |
create_ci_newstate (dfa, nodes, hash) |
internal_function |
1518 |
re_dfa_t *dfa; |
create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, |
1519 |
const re_node_set *nodes; |
re_hashval_t hash) |
|
unsigned int hash; |
|
1520 |
{ |
{ |
1521 |
int i; |
Idx i; |
1522 |
reg_errcode_t err; |
reg_errcode_t err; |
1523 |
re_dfastate_t *newstate; |
re_dfastate_t *newstate; |
1524 |
|
|
1525 |
newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); |
newstate = re_calloc (re_dfastate_t, 1); |
1526 |
if (BE (newstate == NULL, 0)) |
if (BE (newstate == NULL, 0)) |
1527 |
return NULL; |
return NULL; |
1528 |
err = re_node_set_init_copy (&newstate->nodes, nodes); |
err = re_node_set_init_copy (&newstate->nodes, nodes); |
1564 |
Return the new state if succeeded, otherwise return NULL. */ |
Return the new state if succeeded, otherwise return NULL. */ |
1565 |
|
|
1566 |
static re_dfastate_t * |
static re_dfastate_t * |
1567 |
create_cd_newstate (dfa, nodes, context, hash) |
internal_function |
1568 |
re_dfa_t *dfa; |
create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, |
1569 |
const re_node_set *nodes; |
unsigned int context, re_hashval_t hash) |
|
unsigned int context, hash; |
|
1570 |
{ |
{ |
1571 |
int i, nctx_nodes = 0; |
Idx i, nctx_nodes = 0; |
1572 |
reg_errcode_t err; |
reg_errcode_t err; |
1573 |
re_dfastate_t *newstate; |
re_dfastate_t *newstate; |
1574 |
|
|
1575 |
newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); |
newstate = re_calloc (re_dfastate_t, 1); |
1576 |
if (BE (newstate == NULL, 0)) |
if (BE (newstate == NULL, 0)) |
1577 |
return NULL; |
return NULL; |
1578 |
err = re_node_set_init_copy (&newstate->nodes, nodes); |
err = re_node_set_init_copy (&newstate->nodes, nodes); |
1639 |
} |
} |
1640 |
|
|
1641 |
static void |
static void |
1642 |
free_state (state) |
internal_function |
1643 |
re_dfastate_t *state; |
free_state (re_dfastate_t *state) |
1644 |
{ |
{ |
1645 |
re_node_set_free (&state->non_eps_nodes); |
re_node_set_free (&state->non_eps_nodes); |
1646 |
re_node_set_free (&state->inveclosure); |
re_node_set_free (&state->inveclosure); |