mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
feature(head): Introduce NLines to handle negative lines parameters
This commit is contained in:
parent
7b96432eff
commit
ce064dc62e
2 changed files with 35 additions and 4 deletions
|
@ -14,6 +14,7 @@
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Read};
|
||||
use std::path::Path;
|
||||
|
@ -26,6 +27,7 @@ static LONG_HELP: &str = "";
|
|||
enum FilterMode {
|
||||
Bytes(usize),
|
||||
Lines(usize),
|
||||
NLines(usize),
|
||||
}
|
||||
|
||||
struct Settings {
|
||||
|
@ -74,7 +76,6 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
.parse(new_args);
|
||||
|
||||
let use_bytes = matches.opt_present("c");
|
||||
|
||||
// TODO: suffixes (e.g. b, kB, etc.)
|
||||
match matches.opt_str("n") {
|
||||
Some(n) => {
|
||||
|
@ -82,8 +83,17 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
show_error!("cannot specify both --bytes and --lines.");
|
||||
return 1;
|
||||
}
|
||||
match n.parse::<usize>() {
|
||||
Ok(m) => settings.mode = FilterMode::Lines(m),
|
||||
|
||||
match n.parse::<isize>() {
|
||||
Ok(m) => {
|
||||
settings.mode = if m < 0 {
|
||||
let m: usize = m.abs() as usize;
|
||||
FilterMode::NLines(m)
|
||||
} else {
|
||||
let m: usize = m.abs() as usize;
|
||||
FilterMode::Lines(m)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
show_error!("invalid line count '{}': {}", n, e);
|
||||
return 1;
|
||||
|
@ -158,10 +168,11 @@ fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
|
|||
let b = options.len();
|
||||
|
||||
while a < b {
|
||||
let previous = options[a - 1].clone();
|
||||
let current = options[a].clone();
|
||||
let current = current.as_bytes();
|
||||
|
||||
if current.len() > 1 && current[0] == b'-' {
|
||||
if previous != "-n" && current.len() > 1 && current[0] == b'-' {
|
||||
let len = current.len();
|
||||
for pos in 1..len {
|
||||
// Ensure that the argument is only made out of digits
|
||||
|
@ -198,6 +209,17 @@ fn head<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> bool {
|
|||
println!("{}", line.unwrap());
|
||||
}
|
||||
}
|
||||
FilterMode::NLines(count) => {
|
||||
let mut vector: VecDeque<String> = VecDeque::new();
|
||||
|
||||
for line in reader.lines() {
|
||||
vector.push_back(line.unwrap());
|
||||
if vector.len() <= count {
|
||||
continue;
|
||||
}
|
||||
println!("{}", vector.pop_front().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
@ -28,6 +28,15 @@ fn test_stdin_1_line() {
|
|||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_negative_23_line() {
|
||||
new_ucmd!()
|
||||
.args(&["-n", "-23"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_5_chars() {
|
||||
new_ucmd!()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue