mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #1510 from sylvestre/negative_lines
feature(head): Introduce NLines to handle negative lines parameters
This commit is contained in:
commit
279de2d664
2 changed files with 35 additions and 4 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue