3232
3333ENGINES:
3434 backtrack Search with the bounded backtracker regex engine.
35+ lite Search with the regex-lite engine.
3536 meta Search with the meta regex engine.
3637 onepass Search with the one-pass DFA regex engine.
3738 pikevm Search with the PikeVM regex engine.
@@ -40,6 +41,7 @@ ENGINES:
4041 let cmd = args:: next_as_command ( USAGE , p) ?;
4142 match & * cmd {
4243 "backtrack" => nfa:: run_backtrack ( p) ,
44+ "lite" => run_lite ( p) ,
4345 "meta" => run_meta ( p) ,
4446 "onepass" => dfa:: run_onepass ( p) ,
4547 "pikevm" => nfa:: run_pikevm ( p) ,
@@ -219,6 +221,107 @@ OPTIONS:
219221 Ok ( ( ) )
220222}
221223
224+ fn run_lite ( p : & mut lexopt:: Parser ) -> anyhow:: Result < ( ) > {
225+ const USAGE : & ' static str = "\
226+ Executes a search for full matches using the top-level regex-lite engine.
227+
228+ USAGE:
229+ regex-cli find capture lite [-p <pattern> ...] <haystack-path>
230+ regex-cli find capture lite [-p <pattern> ...] -y <haystack>
231+
232+ TIP:
233+ use -h for short docs and --help for long docs
234+
235+ OPTIONS:
236+ %options%
237+ " ;
238+
239+ let mut common = args:: common:: Config :: default ( ) ;
240+ let mut patterns = args:: patterns:: Config :: only_flags ( ) ;
241+ let mut haystack = args:: haystack:: Config :: default ( ) ;
242+ let mut syntax = args:: syntax:: Config :: default ( ) ;
243+ let mut lite = args:: lite:: Config :: default ( ) ;
244+ let mut find = super :: Config :: default ( ) ;
245+ args:: configure (
246+ p,
247+ USAGE ,
248+ & mut [
249+ & mut common,
250+ & mut patterns,
251+ & mut haystack,
252+ & mut syntax,
253+ & mut lite,
254+ & mut find,
255+ ] ,
256+ ) ?;
257+
258+ let pats = patterns. get ( ) ?;
259+ let syn = syntax. syntax ( ) ?;
260+ let mut table = Table :: empty ( ) ;
261+ let ( re, time) = util:: timeitr ( || lite. from_patterns ( & syn, & pats) ) ?;
262+ table. add ( "build regex time" , time) ;
263+
264+ // Check that the haystack is valid UTF-8 since regex-lite doesn't support
265+ // searching arbitrary byte sequences. (At time of writing.)
266+ haystack. get ( ) ?. to_str ( ) ?;
267+
268+ // The top-level API doesn't support regex-automata's more granular Input
269+ // abstraction.
270+ let input = args:: input:: Config :: default ( ) ;
271+ // The top-level API also doesn't use 'Captures' from regex-automata
272+ // directly, but we can map between them with some annoyance.
273+ let group_info = GroupInfo :: new ( [ re. capture_names ( ) ] )
274+ . context ( "could not build capture group info" ) ?;
275+ let mut locs = re. capture_locations ( ) ;
276+ let search = |input : & Input < ' _ > , caps : & mut Captures | {
277+ let haystack = input. haystack ( ) . to_str ( ) . unwrap ( ) ;
278+ caps. set_pattern ( None ) ;
279+ if !re. captures_read_at ( & mut locs, haystack, input. start ( ) ) . is_some ( ) {
280+ return Ok ( ( ) ) ;
281+ }
282+ caps. set_pattern ( Some ( PatternID :: ZERO ) ) ;
283+ for i in 0 ..locs. len ( ) {
284+ use regex_automata:: util:: primitives:: NonMaxUsize ;
285+
286+ let slot_start = i * 2 ;
287+ let slot_end = slot_start + 1 ;
288+ match locs. get ( i) {
289+ None => {
290+ caps. slots_mut ( ) [ slot_start] = None ;
291+ caps. slots_mut ( ) [ slot_end] = None ;
292+ }
293+ Some ( ( start, end) ) => {
294+ caps. slots_mut ( ) [ slot_start] = NonMaxUsize :: new ( start) ;
295+ caps. slots_mut ( ) [ slot_end] = NonMaxUsize :: new ( end) ;
296+ }
297+ }
298+ }
299+ Ok ( ( ) )
300+ } ;
301+ if find. count {
302+ run_counts (
303+ & mut table,
304+ & common,
305+ & find,
306+ & input,
307+ & haystack,
308+ & group_info,
309+ search,
310+ ) ?;
311+ } else {
312+ run_search (
313+ & mut table,
314+ & common,
315+ & find,
316+ & input,
317+ & haystack,
318+ & group_info,
319+ search,
320+ ) ?;
321+ }
322+ Ok ( ( ) )
323+ }
324+
222325/// A function that takes in a bunch of configuration, runs the given search
223326/// routine, and prints out a table of counts.
224327fn run_counts (
0 commit comments