1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 11:07:44 +00:00

Merge pull request #1510 from sylvestre/negative_lines

feature(head): Introduce NLines to handle negative lines parameters
This commit is contained in:
Sylvestre Ledru 2020-05-10 22:50:41 +02:00 committed by GitHub
commit 279de2d664
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 4 deletions

View file

@ -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
}

View file

@ -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!()