1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-02 14:07:46 +00:00

Merge pull request #631 from jbcrail/update-head

Update head.
This commit is contained in:
Heather 2015-05-31 08:46:24 +03:00
commit af21772bd4
7 changed files with 140 additions and 26 deletions

View file

@ -170,6 +170,7 @@ TEST_PROGS := \
false \
fold \
hashsum \
head \
mkdir \
mv \
nl \

View file

@ -25,13 +25,29 @@ mod util;
static NAME: &'static str = "head";
static VERSION: &'static str = "1.0.0";
enum FilterMode {
Bytes(usize),
Lines(usize),
}
struct Settings {
mode: FilterMode,
}
impl Default for Settings {
fn default() -> Settings {
Settings {
mode: FilterMode::Lines(10),
}
}
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut line_count = 10usize;
let mut byte_count = 0usize;
let mut settings: Settings = Default::default();
// handle obsolete -number syntax
let options = match obsolete(&args[1..]) {
(args, Some(n)) => { line_count = n; args },
(args, Some(n)) => { settings.mode = FilterMode::Lines(n); args },
(args, None) => args
};
@ -41,8 +57,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
opts.optopt("c", "bytes", "Print the first K bytes. With the leading '-', print all but the last K bytes", "[-]K");
opts.optopt("n", "lines", "Print the first K lines. With the leading '-', print all but the last K lines", "[-]K");
opts.optflag("h", "help", "help");
opts.optflag("V", "version", "version");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let given_options = match opts.parse(&args) {
Ok (m) => { m }
@ -68,7 +84,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
return 1;
}
match n.parse::<usize>() {
Ok(m) => { line_count = m }
Ok(m) => { settings.mode = FilterMode::Lines(m) }
Err(e) => {
show_error!("invalid line count '{}': {}", n, e);
return 1;
@ -77,7 +93,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
}
None => match given_options.opt_str("c") {
Some(count) => match count.parse::<usize>() {
Ok(m) => byte_count = m,
Ok(m) => settings.mode = FilterMode::Bytes(m),
Err(e)=> {
show_error!("invalid byte count '{}': {}", count, e);
return 1;
@ -89,16 +105,9 @@ pub fn uumain(args: Vec<String>) -> i32 {
let files = given_options.free;
let count =
if use_bytes {
byte_count
} else {
line_count
};
if files.is_empty() {
let mut buffer = BufReader::new(stdin());
head(&mut buffer, count, use_bytes);
head(&mut buffer, &settings);
} else {
let mut multiple = false;
let mut firstime = true;
@ -117,7 +126,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
let path = Path::new(file);
let reader = File::open(&path).unwrap();
let mut buffer = BufReader::new(reader);
if !head(&mut buffer, count, use_bytes) {
if !head(&mut buffer, &settings) {
break;
}
}
@ -161,20 +170,23 @@ fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
}
// TODO: handle errors on read
fn head<T: Read>(reader: &mut BufReader<T>, count: usize, use_bytes: bool) -> bool {
if use_bytes {
fn head<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> bool {
match settings.mode {
FilterMode::Bytes(count) => {
for byte in reader.bytes().take(count) {
if !pipe_print!("{}", byte.unwrap() as char) {
return false;
}
}
} else {
},
FilterMode::Lines(count) => {
for line in reader.lines().take(count) {
if !pipe_print!("{}", line.unwrap()) {
if !pipe_println!("{}", line.unwrap()) {
return false;
}
}
}
}
true
}

24
test/fixtures/head/lorem_ipsum.txt vendored Normal file
View file

@ -0,0 +1,24 @@
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Nunc interdum suscipit sem vel ornare.
Proin euismod,
justo sed mollis dictum,
eros urna ultricies augue,
eu pharetra mi ex id ante.
Duis convallis porttitor aliquam.
Nunc vitae tincidunt ex.
Suspendisse iaculis ligula ac diam consectetur lacinia.
Donec vel velit dui.
Etiam fringilla,
dolor quis tempor vehicula,
lacus turpis bibendum velit,
et pellentesque elit odio a magna.
Cras vulputate tortor non libero vehicula euismod.
Aliquam tincidunt nisl eget enim cursus,
viverra sagittis magna commodo.
Cras rhoncus egestas leo nec blandit.
Suspendisse potenti.
Etiam ullamcorper leo vel lacus vestibulum,
cursus semper eros efficitur.
In hac habitasse platea dictumst.
Phasellus scelerisque vehicula fringilla.

View file

@ -0,0 +1 @@
Lorem ipsum dolor sit amet,

View file

@ -0,0 +1 @@
Lorem

View file

@ -0,0 +1,10 @@
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Nunc interdum suscipit sem vel ornare.
Proin euismod,
justo sed mollis dictum,
eros urna ultricies augue,
eu pharetra mi ex id ante.
Duis convallis porttitor aliquam.
Nunc vitae tincidunt ex.
Suspendisse iaculis ligula ac diam consectetur lacinia.

65
test/head.rs Normal file
View file

@ -0,0 +1,65 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./head";
static INPUT: &'static str = "lorem_ipsum.txt";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_stdin_default() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_default.expected"));
}
#[test]
fn test_stdin_1_line_obsolete() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-1"]), get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_stdin_1_line() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-n", "1"]), get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_stdin_5_chars() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-c", "5"]), get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected"));
}
#[test]
fn test_single_default() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_default.expected"));
}
#[test]
fn test_single_1_line_obsolete() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-1", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_single_1_line() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-n", "1", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_single_5_chars() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-c", "5", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected"));
}