1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-06-30 22:23:44 +02:00
This commit is contained in:
Andrew Gallant
2016-03-29 21:21:34 -04:00
parent 4ae67a8587
commit 79a51029c1
3 changed files with 210 additions and 66 deletions

View File

@ -20,9 +20,11 @@ use docopt::Docopt;
use regex::bytes::Regex;
use literals::LiteralSets;
use search::{LineSearcher, LineSearcherBuilder};
mod literals;
mod nonl;
mod search;
pub type Result<T> = result::Result<T, Box<Error + Send + Sync>>;
@ -46,20 +48,36 @@ fn main() {
}
fn run(args: &Args) -> Result<u64> {
let expr = try!(parse(&args.arg_pattern));
let literals = LiteralSets::create(&expr);
// println!("{:?}", literals);
// println!("{:?}", literals.to_matcher());
let re = Regex::new(&expr.to_string()).unwrap();
if args.arg_file.is_empty() {
let expr = try!(parse(&args.arg_pattern));
let literals = LiteralSets::create(&expr);
let re = Regex::new(&expr.to_string()).unwrap();
let _stdin = io::stdin();
let stdin = _stdin.lock();
run_by_line(args, &re, stdin)
} else {
run_mmap(args, &re)
let searcher =
try!(LineSearcherBuilder::new(&args.arg_pattern).create());
run_mmap(args, &searcher)
}
}
fn run_mmap(args: &Args, searcher: &LineSearcher) -> Result<u64> {
use memmap::{Mmap, Protection};
assert!(args.arg_file.len() == 1);
let mut wtr = io::BufWriter::new(io::stdout());
let mut count = 0;
let mmap = try!(Mmap::open_path(&args.arg_file[0], Protection::Read));
let text = unsafe { mmap.as_slice() };
for m in searcher.search(text) {
try!(wtr.write(&text[m.start..m.end]));
try!(wtr.write(b"\n"));
count += 1;
}
Ok(count)
}
fn run_by_line<B: BufRead>(
args: &Args,
re: &Regex,
@ -84,31 +102,6 @@ fn run_by_line<B: BufRead>(
Ok(count)
}
fn run_mmap(args: &Args, re: &Regex) -> Result<u64> {
use memchr::{memchr, memrchr};
use memmap::{Mmap, Protection};
assert!(args.arg_file.len() == 1);
let mut wtr = io::BufWriter::new(io::stdout());
let mut count = 0;
let mmap = try!(Mmap::open_path(&args.arg_file[0], Protection::Read));
let text = unsafe { mmap.as_slice() };
let mut start = 0;
while let Some((s, e)) = re.find(&text[start..]) {
let (s, e) = (start + s, start + e);
let prevnl = memrchr(b'\n', &text[0..s]).map_or(0, |i| i + 1);
let nextnl = memchr(b'\n', &text[e..]).map_or(text.len(), |i| e + i);
try!(wtr.write(&text[prevnl..nextnl]));
try!(wtr.write(b"\n"));
start = nextnl + 1;
count += 1;
if start >= text.len() {
break;
}
}
Ok(count)
}
fn parse(re: &str) -> Result<syntax::Expr> {
let expr =
try!(syntax::ExprBuilder::new()