Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/uu/tr/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::{
io::{BufRead, Write},
ops::Not,
};
use uucore::error::UError;
use uucore::error::{UError, UResult, USimpleError};
use uucore::show_warning;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -608,23 +608,33 @@ impl SymbolTranslator for SqueezeOperation {
}
}

pub fn translate_input<T, R, W>(input: &mut R, output: &mut W, mut translator: T)
pub fn translate_input<T, R, W>(input: &mut R, output: &mut W, mut translator: T) -> UResult<()>
where
T: SymbolTranslator,
R: BufRead,
W: Write,
{
let mut buf = Vec::new();
let mut output_buf = Vec::new();

while let Ok(length) = input.read_until(b'\n', &mut buf) {
if length == 0 {
break;
} else {
let filtered = buf.iter().filter_map(|c| translator.translate(*c));
output_buf.extend(filtered);
output.write_all(&output_buf).unwrap();
break; // EOF reached
}

let filtered = buf.iter().filter_map(|&c| translator.translate(c));
output_buf.extend(filtered);

if let Err(e) = output.write_all(&output_buf) {
return Err(USimpleError::new(
1,
format!("{}: write error: {}", uucore::util_name(), e),
));
}

buf.clear();
output_buf.clear();
}

Ok(())
}
10 changes: 5 additions & 5 deletions src/uu/tr/src/tr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,24 +132,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let delete_op = DeleteOperation::new(set1);
let squeeze_op = SqueezeOperation::new(set2);
let op = delete_op.chain(squeeze_op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op)?;
} else {
let op = DeleteOperation::new(set1);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op)?;
}
} else if squeeze_flag {
if sets_len < 2 {
let op = SqueezeOperation::new(set1);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op)?;
} else {
let translate_op = TranslateOperation::new(set1, set2.clone())?;
let squeeze_op = SqueezeOperation::new(set2);
let op = translate_op.chain(squeeze_op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op)?;
}
} else {
let op = TranslateOperation::new(set1, set2)?;
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
translate_input(&mut locked_stdin, &mut buffered_stdout, op)?;
}
Ok(())
}
Expand Down
9 changes: 9 additions & 0 deletions tests/by-util/test_tr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ fn test_invalid_arg() {
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
}

#[test]
fn test_invalid_input() {
new_ucmd!()
.args(&["1", "1", "<", "."])
.fails()
.code_is(1)
.stderr_contains("tr: extra operand '<'");
}

#[test]
fn test_to_upper() {
new_ucmd!()
Expand Down
Loading