1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-31 21:17:46 +00:00

Merge pull request #579 from jbcrail/update-fold

Update fold and add tests.
This commit is contained in:
Heather 2015-05-08 08:05:38 +03:00
commit 7cb74885c4
7 changed files with 125 additions and 21 deletions

View file

@ -162,6 +162,7 @@ TEST_PROGS := \
cp \
env \
factor \
fold \
mkdir \
mv \
nl \

View file

@ -1,5 +1,5 @@
#![crate_name = "fold"]
#![feature(collections, core, old_io, old_path, rustc_private, unicode)]
#![feature(collections, rustc_private)]
/*
* This file is part of the uutils coreutils package.
@ -13,9 +13,9 @@
extern crate getopts;
extern crate libc;
use std::old_io as io;
use std::old_io::fs::File;
use std::old_io::BufferedReader;
use std::fs::File;
use std::io::{BufRead, BufReader, Read, stdin, Write};
use std::path::Path;
#[path = "../common/util.rs"]
#[macro_use]
@ -25,7 +25,7 @@ static NAME: &'static str = "fold";
static VERSION: &'static str = "1.0.0";
pub fn uumain(args: Vec<String>) -> i32 {
let (args, obs_width) = handle_obsolete(args.as_slice());
let (args, obs_width) = handle_obsolete(&args[..]);
let program = args[0].clone();
let opts = [
@ -36,7 +36,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
getopts::optflag("V", "version", "output version information and exit")
];
let matches = match getopts::getopts(args.tail(), &opts) {
let matches = match getopts::getopts(&args[1..], &opts) {
Ok(m) => m,
Err(f) => crash!(1, "{}", f)
};
@ -82,8 +82,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
fn handle_obsolete(args: &[String]) -> (Vec<String>, Option<String>) {
for (i, arg) in args.iter().enumerate() {
let slice = arg.as_slice();
if slice.char_at(0) == '-' && slice.len() > 1 && slice.char_at(1).is_digit(10) {
let slice = &arg;
if slice.chars().next().unwrap() == '-' && slice.len() > 1 && slice.chars().nth(1).unwrap().is_digit(10) {
return (args[..i].to_vec() + &args[i + 1..],
Some(slice[1..].to_string()));
}
@ -94,16 +94,16 @@ fn handle_obsolete(args: &[String]) -> (Vec<String>, Option<String>) {
#[inline]
fn fold(filenames: Vec<String>, bytes: bool, spaces: bool, width: usize) {
for filename in filenames.iter() {
let filename: &str = filename.as_slice();
let filename: &str = &filename;
let mut stdin_buf;
let mut file_buf;
let buffer = BufferedReader::new(
let buffer = BufReader::new(
if filename == "-" {
stdin_buf = io::stdio::stdin_raw();
&mut stdin_buf as &mut Reader
stdin_buf = stdin();
&mut stdin_buf as &mut Read
} else {
file_buf = safe_unwrap!(File::open(&Path::new(filename)));
&mut file_buf as &mut Reader
file_buf = safe_unwrap!(File::open(Path::new(filename)));
&mut file_buf as &mut Read
}
);
fold_file(buffer, bytes, spaces, width);
@ -111,11 +111,9 @@ fn fold(filenames: Vec<String>, bytes: bool, spaces: bool, width: usize) {
}
#[inline]
fn fold_file<T: io::Reader>(file: BufferedReader<T>, bytes: bool, spaces: bool, width: usize) {
let mut file = file;
for line in file.lines() {
let line_string = safe_unwrap!(line);
let mut line = line_string.as_slice();
fn fold_file<T: Read>(mut file: BufReader<T>, bytes: bool, spaces: bool, width: usize) {
let mut line = String::new();
while safe_unwrap!(file.read_line(&mut line)) > 0 {
if bytes {
let len = line.len();
let mut i = 0;
@ -143,15 +141,15 @@ fn fold_file<T: io::Reader>(file: BufferedReader<T>, bytes: bool, spaces: bool,
println!("");
continue;
}
line = &line[..line.len() - 1];
len -= 1;
line.truncate(len);
}
let mut output = String::new();
let mut count = 0;
for (i, ch) in line.chars().enumerate() {
if count >= width {
let (val, ncount) = {
let slice = output.as_slice();
let slice = &output[..];
let (out, val, ncount) =
if spaces && i + 1 < len {
match rfind_whitespace(slice) {

1
test/fixtures/fold/lorem_ipsum.txt vendored Normal file
View file

@ -0,0 +1 @@
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,20 @@
Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Nunc interdum suscipit
sem vel ornare. Proin euismod, justo sed
mollis dictum, eros urna ultricies augu
e, eu pharetra mi ex id ante. Duis conva
llis porttitor aliquam. Nunc vitae tinci
dunt ex. Suspendisse iaculis ligula ac d
iam 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 eui
smod. Aliquam tincidunt nisl eget enim c
ursus, viverra sagittis magna commodo. C
ras rhoncus egestas leo nec blandit. Sus
pendisse potenti. Etiam ullamcorper leo
vel lacus vestibulum, cursus semper eros
efficitur. In hac habitasse platea dict
umst. Phasellus scelerisque vehicula fri
ngilla.

View file

@ -0,0 +1,21 @@
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,10 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc interdum suscipit
sem vel ornare. Proin euismod, justo sed mollis dictum, eros urna ultricies augu
e, eu pharetra mi ex id ante. Duis convallis porttitor aliquam. Nunc vitae tinci
dunt 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 eui
smod. Aliquam tincidunt nisl eget enim cursus, viverra sagittis magna commodo. C
ras rhoncus egestas leo nec blandit. Suspendisse potenti. Etiam ullamcorper leo
vel lacus vestibulum, cursus semper eros efficitur. In hac habitasse platea dict
umst. Phasellus scelerisque vehicula fringilla.

53
test/fold.rs Normal file
View file

@ -0,0 +1,53 @@
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;
static PROGNAME: &'static str = "./fold";
#[test]
fn test_default_80_column_wrap() {
let po = Command::new(PROGNAME)
.arg("lorem_ipsum.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
fold_helper(po.stdout, "lorem_ipsum_80_column.expected");
}
#[test]
fn test_40_column_hard_cutoff() {
let po = Command::new(PROGNAME)
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
fold_helper(po.stdout, "lorem_ipsum_40_column_hard.expected");
}
#[test]
fn test_40_column_word_boundary() {
let po = Command::new(PROGNAME)
.arg("-s")
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
fold_helper(po.stdout, "lorem_ipsum_40_column_word.expected");
}
fn fold_helper(output: Vec<u8>, filename: &str) {
let mut f = File::open(Path::new(filename)).unwrap_or_else(|err| {
panic!("{}", err)
});
let mut expected = vec!();
match f.read_to_end(&mut expected) {
Ok(_) => {},
Err(err) => panic!("{}", err)
}
assert_eq!(String::from_utf8(output).unwrap(), String::from_utf8(expected).unwrap());
}