mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 20:47:46 +00:00
Merge pull request #749 from jbcrail/refactor-tail-2
tail: use read_line/read instead of lines/bytes
This commit is contained in:
commit
bc0dd2006c
1 changed files with 63 additions and 36 deletions
|
@ -248,56 +248,83 @@ fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
|
||||||
(options, None)
|
(options, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! tail_impl (
|
fn tail<T: Read>(reader: &mut BufReader<T>, settings: &Settings) {
|
||||||
($kind:ty, $kindfn:ident, $kindprint:ident, $reader:ident, $count:expr, $beginning:expr) => ({
|
// Read through each line/char and store them in a ringbuffer that always
|
||||||
// read through each line and store them in a ringbuffer that always contains
|
// contains count lines/chars. When reaching the end of file, output the
|
||||||
// count lines/chars. When reaching the end of file, output the data in the
|
// data in the ringbuf.
|
||||||
// ringbuf.
|
match settings.mode {
|
||||||
let mut count = $count;
|
FilterMode::Lines(mut count) => {
|
||||||
let mut ringbuf: VecDeque<$kind> = VecDeque::new();
|
let mut ringbuf: VecDeque<String> = VecDeque::new();
|
||||||
let data = $reader.$kindfn().skip(
|
let mut skip = if settings.beginning {
|
||||||
if $beginning {
|
|
||||||
let temp = count;
|
let temp = count;
|
||||||
count = ::std::usize::MAX;
|
count = ::std::usize::MAX;
|
||||||
temp - 1
|
temp - 1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
};
|
||||||
);
|
loop {
|
||||||
for io_datum in data {
|
let mut datum = String::new();
|
||||||
match io_datum {
|
match reader.read_line(&mut datum) {
|
||||||
Ok(datum) => {
|
Ok(0) => break,
|
||||||
if count <= ringbuf.len() {
|
Ok(_) => {
|
||||||
ringbuf.pop_front();
|
if skip > 0 {
|
||||||
}
|
skip -= 1;
|
||||||
ringbuf.push_back(datum);
|
} else {
|
||||||
|
if count <= ringbuf.len() {
|
||||||
|
ringbuf.pop_front();
|
||||||
|
}
|
||||||
|
ringbuf.push_back(datum);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => panic!(err)
|
||||||
}
|
}
|
||||||
Err(err) => panic!(err)
|
|
||||||
}
|
}
|
||||||
}
|
let mut stdout = stdout();
|
||||||
let mut stdout = stdout();
|
for datum in ringbuf.iter() {
|
||||||
for datum in ringbuf.iter() {
|
print_string(&mut stdout, datum);
|
||||||
$kindprint(&mut stdout, datum);
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
fn tail<T: Read>(reader: &mut BufReader<T>, settings: &Settings) {
|
|
||||||
match settings.mode {
|
|
||||||
FilterMode::Lines(count) => {
|
|
||||||
tail_impl!(String, lines, print_string, reader, count, settings.beginning)
|
|
||||||
},
|
},
|
||||||
FilterMode::Bytes(count) => {
|
FilterMode::Bytes(mut count) => {
|
||||||
tail_impl!(u8, bytes, print_byte, reader, count, settings.beginning)
|
let mut ringbuf: VecDeque<u8> = VecDeque::new();
|
||||||
|
let mut skip = if settings.beginning {
|
||||||
|
let temp = count;
|
||||||
|
count = ::std::usize::MAX;
|
||||||
|
temp - 1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
loop {
|
||||||
|
let mut datum = [0; 1];
|
||||||
|
match reader.read(&mut datum) {
|
||||||
|
Ok(0) => break,
|
||||||
|
Ok(_) => {
|
||||||
|
if skip > 0 {
|
||||||
|
skip -= 1;
|
||||||
|
} else {
|
||||||
|
if count <= ringbuf.len() {
|
||||||
|
ringbuf.pop_front();
|
||||||
|
}
|
||||||
|
ringbuf.push_back(datum[0]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => panic!(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut stdout = stdout();
|
||||||
|
for datum in ringbuf.iter() {
|
||||||
|
print_byte(&mut stdout, datum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we follow the file, sleep a bit and print the rest if the file has grown.
|
// if we follow the file, sleep a bit and print the rest if the file has grown.
|
||||||
while settings.follow {
|
while settings.follow {
|
||||||
sleep(Duration::new(0, settings.sleep_msec*1000));
|
sleep(Duration::new(0, settings.sleep_msec*1000));
|
||||||
for io_line in reader.lines() {
|
loop {
|
||||||
match io_line {
|
let mut datum = String::new();
|
||||||
Ok(line) => print!("{}", line),
|
match reader.read_line(&mut datum) {
|
||||||
|
Ok(0) => break,
|
||||||
|
Ok(_) => print!("{}", datum),
|
||||||
Err(err) => panic!(err)
|
Err(err) => panic!(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue