1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
25 * posix regex record executor
26 * multiple record sized-buffer interface
32 * call regnexec() on records selected by Boyer-Moore
36 regrexec(const regex_t
* p
, const char* s
, size_t len
, size_t nmatch
, regmatch_t
* match
, regflags_t flags
, int sep
, void* handle
, regrecord_t record
)
38 register unsigned char* buf
= (unsigned char*)s
;
39 register unsigned char* beg
;
40 register unsigned char* l
;
41 register unsigned char* r
;
42 register unsigned char* x
;
43 register size_t* skip
;
44 register size_t* fail
;
45 register Bm_mask_t
** mask
;
46 register size_t index
;
59 if (!s
|| !p
|| !(env
= p
->env
) || (e
= env
->rex
)->type
!= REX_BM
)
61 inv
= (flags
& REG_INVERT
) != 0;
62 buf
= beg
= (unsigned char*)s
;
64 mid
= (len
< e
->re
.bm
.right
) ? 0 : (len
- e
->re
.bm
.right
);
68 complete
= e
->re
.bm
.complete
&& !nmatch
;
69 exactlen
= e
->re
.bm
.size
;
70 leftlen
= e
->re
.bm
.left
+ exactlen
;
71 rightlen
= exactlen
+ e
->re
.bm
.right
;
75 while ((index
+= skip
[buf
[index
]]) < mid
);
79 m
= mask
[n
= exactlen
- 1][buf
[index
]];
84 } while (m
&= mask
[n
][buf
[--index
]]);
85 if ((index
+= fail
[n
+ 1]) < len
)
96 r
= (l
= buf
+ index
) + exactlen
;
103 if ((r
- l
) < leftlen
)
105 while (r
< end
&& *r
!= sep
)
107 if ((r
- (buf
+ index
)) < rightlen
)
109 if (complete
|| (env
->rex
= ((r
- l
) > 128) ? e
: e
->next
) && !(n
= regnexec(p
, (char*)l
, r
- l
, nmatch
, match
, flags
)))
117 while (x
< l
&& *x
!= sep
)
119 if (n
= (*record
)(handle
, (char*)beg
, x
- beg
))
124 else if (n
= (*record
)(handle
, (char*)l
, r
- l
))
126 if ((index
= (r
- buf
) + leftlen
) >= len
)
128 n
= (inv
&& (++r
- buf
) < len
) ? (*record
)(handle
, (char*)r
, (buf
+ len
) - r
): 0;
133 else if (n
!= REG_NOMATCH
)
138 if ((index
+= exactlen
) >= mid
)