summaryrefslogtreecommitdiffstats
path: root/src/search_buffer.rs
diff options
context:
space:
mode:
authorBalaji Sivaraman <balaji@balajisivaraman.com>2018-02-21 22:16:45 +0530
committerAndrew Gallant <jamslam@gmail.com>2018-03-10 10:15:19 -0500
commitb006943c01561a4ae5b928081d1bb4087b599e19 (patch)
tree88c402f4edc91b808260c9c7c9ea4e0a5790c089 /src/search_buffer.rs
parent91d0756f62790356012d692a7b340df92b54beac (diff)
search: add -b/--byte-offset flag
This commit adds support for printing 0-based byte offset before each line. We handle corner cases such as `-o/--only-matching` and `-C/--context` as well. Closes #812
Diffstat (limited to 'src/search_buffer.rs')
-rw-r--r--src/search_buffer.rs40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/search_buffer.rs b/src/search_buffer.rs
index 11b561ea..fa446f78 100644
--- a/src/search_buffer.rs
+++ b/src/search_buffer.rs
@@ -23,6 +23,7 @@ pub struct BufferSearcher<'a, W: 'a> {
buf: &'a [u8],
match_count: u64,
line_count: Option<u64>,
+ byte_offset: Option<u64>,
last_line: usize,
}
@@ -41,10 +42,21 @@ impl<'a, W: WriteColor> BufferSearcher<'a, W> {
buf: buf,
match_count: 0,
line_count: None,
+ byte_offset: None,
last_line: 0,
}
}
+ /// If enabled, searching will print a 0-based offset of the
+ /// matching line (or the actual match if -o is specified) before
+ /// printing the line itself.
+ ///
+ /// Disabled by default.
+ pub fn byte_offset(mut self, yes: bool) -> Self {
+ self.opts.byte_offset = yes;
+ self
+ }
+
/// If enabled, searching will print a count instead of each match.
///
/// Disabled by default.
@@ -120,6 +132,9 @@ impl<'a, W: WriteColor> BufferSearcher<'a, W> {
self.match_count = 0;
self.line_count = if self.opts.line_number { Some(0) } else { None };
+ // The memory map searcher uses one contiguous block of bytes, so the
+ // offsets given the printer are sufficient to compute the byte offset.
+ self.byte_offset = if self.opts.byte_offset { Some(0) } else { None };
let mut last_end = 0;
for m in self.grep.iter(self.buf) {
if self.opts.invert_match {
@@ -158,7 +173,7 @@ impl<'a, W: WriteColor> BufferSearcher<'a, W> {
self.add_line(end);
self.printer.matched(
self.grep.regex(), self.path, self.buf,
- start, end, self.line_count);
+ start, end, self.line_count, self.byte_offset);
}
#[inline(always)]
@@ -272,6 +287,29 @@ and exhibited clearly, with a label attached.\
}
#[test]
+ fn byte_offset() {
+ let (_, out) = search(
+ "Sherlock", SHERLOCK, |s| s.byte_offset(true));
+ assert_eq!(out, "\
+/baz.rs:0:For the Doctor Watsons of this world, as opposed to the Sherlock
+/baz.rs:129:be, to a very large extent, the result of luck. Sherlock Holmes
+");
+ }
+
+ #[test]
+ fn byte_offset_inverted() {
+ let (_, out) = search("Sherlock", SHERLOCK, |s| {
+ s.invert_match(true).byte_offset(true)
+ });
+ assert_eq!(out, "\
+/baz.rs:65:Holmeses, success in the province of detective work must always
+/baz.rs:193:can extract a clew from a wisp of straw or a flake of cigar ash;
+/baz.rs:258:but Doctor Watson has to have it taken out for him and dusted,
+/baz.rs:321:and exhibited clearly, with a label attached.
+");
+ }
+
+ #[test]
fn count() {
let (count, out) = search(
"Sherlock", SHERLOCK, |s| s.count(true));