Skip to content
Closed
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
18 changes: 11 additions & 7 deletions src/uu/od/src/multifile_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

// spell-checker:ignore (ToDO) multifile curr fnames fname xfrd fillloop mockstream

use std::ffi::OsStr;
use std::fs::File;
use std::io;
#[cfg(unix)]
Expand All @@ -16,7 +17,7 @@ use uucore::{display::Quotable, error::strip_errno, show_error, translate};
const SKIP_BUFFER_SIZE: usize = 16 * 1024;

pub enum InputSource<'a> {
FileName(&'a str),
FileName(&'a OsStr),
Stdin,
}

Expand Down Expand Up @@ -55,7 +56,7 @@ pub struct MultifileReader<'a> {
ni: Vec<InputSource<'a>>,
curr_file: Option<CurrentReader>,
any_err: bool,
file_name: Option<&'a str>,
file_name: Option<&'a OsStr>,
}

pub trait HasError {
Expand Down Expand Up @@ -238,7 +239,10 @@ impl io::Read for MultifileReader<'_> {
Err(e) => {
show_error!(
"{}: {}",
self.file_name.unwrap_or("I/O"),
self.file_name
.unwrap_or(OsStr::new("I/O"))
.maybe_quote()
.external(true),
strip_errno(&e)
);
self.any_err = true;
Expand Down Expand Up @@ -275,11 +279,11 @@ mod tests {
fn test_multi_file_reader_one_read() {
let mut file1 = NamedTempFile::new().unwrap();
file1.write_all(b"abcd").unwrap();
let path1 = file1.path().to_str().unwrap();
let path1 = file1.path().as_os_str();

let mut file2 = NamedTempFile::new().unwrap();
file2.write_all(b"ABCD").unwrap();
let path2 = file2.path().to_str().unwrap();
let path2 = file2.path().as_os_str();

let inputs = vec![InputSource::FileName(path1), InputSource::FileName(path2)];
let mut v = [0; 10];
Expand All @@ -295,11 +299,11 @@ mod tests {
fn test_multi_file_reader_two_reads() {
let mut file1 = NamedTempFile::new().unwrap();
file1.write_all(b"abcd").unwrap();
let path1 = file1.path().to_str().unwrap();
let path1 = file1.path().as_os_str();

let mut file2 = NamedTempFile::new().unwrap();
file2.write_all(b"ABCD").unwrap();
let path2 = file2.path().to_str().unwrap();
let path2 = file2.path().as_os_str();

let inputs = vec![InputSource::FileName(path1), InputSource::FileName(path2)];
let mut v = [0; 5];
Expand Down
28 changes: 18 additions & 10 deletions src/uu/od/src/od.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct OdOptions {
skip_bytes: u64,
read_bytes: Option<u64>,
label: Option<u64>,
input_strings: Vec<String>,
input_strings: Vec<OsString>,
formats: Vec<ParsedFormatterItemInfo>,
line_bytes: usize,
output_duplicates: bool,
Expand Down Expand Up @@ -253,12 +253,16 @@ impl OdOptions {
/// opens the input and calls `odfunc` to process the input.
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args.collect_ignore();
let raw_args: Vec<OsString> = args.iter().map(OsString::from).collect();
let raw_args: Vec<OsString> = args.collect();
// Only used to look up how options were spelled; file operands keep their raw form.
let args: Vec<String> = raw_args
.iter()
.map(|arg| arg.to_string_lossy().into_owned())
.collect();

let clap_opts = uu_app();

let clap_matches = uucore::clap_localization::handle_clap_result(clap_opts, &args)?;
let clap_matches = uucore::clap_localization::handle_clap_result(clap_opts, &raw_args)?;

// Kept for the caret in SIZE diagnostics, which echoes the command line.
let diag_args = uucore::diagnostics::capture(&raw_args);
Expand Down Expand Up @@ -511,6 +515,7 @@ pub fn uu_app() -> Command {
Arg::new(options::FILENAME)
.hide(true)
.action(ArgAction::Append)
.value_parser(clap::value_parser!(OsString))
.value_hint(clap::ValueHint::FilePath),
)
}
Expand Down Expand Up @@ -597,7 +602,7 @@ where

/// Extract and display printable strings from input (od -S option)
fn extract_strings_from_input(
input_strings: &[String],
input_strings: &[OsString],
skip_bytes: u64,
read_bytes: Option<u64>,
min_length: usize,
Expand Down Expand Up @@ -788,12 +793,15 @@ fn write_bytes(
}

/// Helper function to convert input strings to InputSource
fn map_input_strings(input_strings: &[String]) -> Vec<InputSource<'_>> {
fn map_input_strings(input_strings: &[OsString]) -> Vec<InputSource<'_>> {
input_strings
.iter()
.map(|w| match w as &str {
"-" => InputSource::Stdin,
x => InputSource::FileName(x),
.map(|w| {
if w == "-" {
InputSource::Stdin
} else {
InputSource::FileName(w)
}
})
.collect()
}
Expand All @@ -803,7 +811,7 @@ fn map_input_strings(input_strings: &[String]) -> Vec<InputSource<'_>> {
/// `skip_bytes` is the number of bytes skipped from the input
/// `read_bytes` is an optional limit to the number of bytes to read
fn open_input_peek_reader(
input_strings: &[String],
input_strings: &[OsString],
skip_bytes: u64,
read_bytes: Option<u64>,
) -> UResult<PeekReader<BufReader<PartialReader<MultifileReader<'_>>>>> {
Expand Down
Loading
Loading