1
Fork 0
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:
Anuvrat Parashar 2020-05-10 21:31:58 +02:00 committed by Sylvestre Ledru
parent 7b96432eff
commit ce064dc62e
2 changed files with 35 additions and 4 deletions

View file

@ -14,6 +14,7 @@
#[macro_use] #[macro_use]
extern crate uucore; extern crate uucore;
use std::collections::VecDeque;
use std::fs::File; use std::fs::File;
use std::io::{stdin, BufRead, BufReader, Read}; use std::io::{stdin, BufRead, BufReader, Read};
use std::path::Path; use std::path::Path;
@ -26,6 +27,7 @@ static LONG_HELP: &str = "";
enum FilterMode { enum FilterMode {
Bytes(usize), Bytes(usize),
Lines(usize), Lines(usize),
NLines(usize),
} }
struct Settings { struct Settings {
@ -74,7 +76,6 @@ pub fn uumain(args: Vec<String>) -> i32 {
.parse(new_args); .parse(new_args);
let use_bytes = matches.opt_present("c"); let use_bytes = matches.opt_present("c");
// TODO: suffixes (e.g. b, kB, etc.) // TODO: suffixes (e.g. b, kB, etc.)
match matches.opt_str("n") { match matches.opt_str("n") {
Some(n) => { Some(n) => {
@ -82,8 +83,17 @@ pub fn uumain(args: Vec<String>) -> i32 {
show_error!("cannot specify both --bytes and --lines."); show_error!("cannot specify both --bytes and --lines.");
return 1; 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) => { Err(e) => {
show_error!("invalid line count '{}': {}", n, e); show_error!("invalid line count '{}': {}", n, e);
return 1; return 1;
@ -158,10 +168,11 @@ fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
let b = options.len(); let b = options.len();
while a < b { while a < b {
let previous = options[a - 1].clone();
let current = options[a].clone(); let current = options[a].clone();
let current = current.as_bytes(); 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(); let len = current.len();
for pos in 1..len { for pos in 1..len {
// Ensure that the argument is only made out of digits // 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()); 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 true
} }

View file

@ -28,6 +28,15 @@ fn test_stdin_1_line() {
.stdout_is_fixture("lorem_ipsum_1_line.expected"); .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] #[test]
fn test_stdin_5_chars() { fn test_stdin_5_chars() {
new_ucmd!() new_ucmd!()