mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #2749 from thomasqueirozb/utils_uresult
basename+date+fold+nl+nproc+shuf+uname: use UResult
This commit is contained in:
commit
fe286fa8c8
7 changed files with 145 additions and 123 deletions
|
@ -7,11 +7,10 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) fullname
|
// spell-checker:ignore (ToDO) fullname
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use std::path::{is_separator, PathBuf};
|
use std::path::{is_separator, PathBuf};
|
||||||
|
use uucore::display::Quotable;
|
||||||
|
use uucore::error::{UResult, UUsageError};
|
||||||
use uucore::InvalidEncodingHandling;
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
static SUMMARY: &str = "Print NAME with any leading directory components removed
|
static SUMMARY: &str = "Print NAME with any leading directory components removed
|
||||||
|
@ -32,7 +31,8 @@ pub mod options {
|
||||||
pub static ZERO: &str = "zero";
|
pub static ZERO: &str = "zero";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args
|
let args = args
|
||||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
.accept_any();
|
.accept_any();
|
||||||
|
@ -44,12 +44,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
// too few arguments
|
// too few arguments
|
||||||
if !matches.is_present(options::NAME) {
|
if !matches.is_present(options::NAME) {
|
||||||
crash!(
|
return Err(UUsageError::new(1, "missing operand".to_string()));
|
||||||
1,
|
|
||||||
"{1}\nTry '{0} --help' for more information.",
|
|
||||||
uucore::execution_phrase(),
|
|
||||||
"missing operand"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let opt_suffix = matches.is_present(options::SUFFIX);
|
let opt_suffix = matches.is_present(options::SUFFIX);
|
||||||
|
@ -58,12 +53,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let multiple_paths = opt_suffix || opt_multiple;
|
let multiple_paths = opt_suffix || opt_multiple;
|
||||||
// too many arguments
|
// too many arguments
|
||||||
if !multiple_paths && matches.occurrences_of(options::NAME) > 2 {
|
if !multiple_paths && matches.occurrences_of(options::NAME) > 2 {
|
||||||
crash!(
|
return Err(UUsageError::new(
|
||||||
1,
|
1,
|
||||||
"extra operand '{1}'\nTry '{0} --help' for more information.",
|
format!(
|
||||||
uucore::execution_phrase(),
|
"extra operand {}",
|
||||||
matches.values_of(options::NAME).unwrap().nth(2).unwrap()
|
matches
|
||||||
);
|
.values_of(options::NAME)
|
||||||
|
.unwrap()
|
||||||
|
.nth(2)
|
||||||
|
.unwrap()
|
||||||
|
.quote()
|
||||||
|
),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let suffix = if opt_suffix {
|
let suffix = if opt_suffix {
|
||||||
|
@ -89,7 +90,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
print!("{}{}", basename(path, suffix), line_ending);
|
print!("{}{}", basename(path, suffix), line_ending);
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
|
|
@ -18,6 +18,9 @@ use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "redox")))]
|
||||||
|
use uucore::error::FromIo;
|
||||||
|
use uucore::error::{UResult, USimpleError};
|
||||||
use uucore::show_error;
|
use uucore::show_error;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winapi::{
|
use winapi::{
|
||||||
|
@ -137,7 +140,8 @@ impl<'a> From<&'a str> for Rfc3339Format {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let syntax = format!(
|
let syntax = format!(
|
||||||
"{0} [OPTION]... [+FORMAT]...
|
"{0} [OPTION]... [+FORMAT]...
|
||||||
{0} [OPTION]... [MMDDhhmm[[CC]YY][.ss]]",
|
{0} [OPTION]... [MMDDhhmm[[CC]YY][.ss]]",
|
||||||
|
@ -147,8 +151,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
|
|
||||||
let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
|
let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
|
||||||
if !form.starts_with('+') {
|
if !form.starts_with('+') {
|
||||||
show_error!("invalid date {}", form.quote());
|
return Err(USimpleError::new(
|
||||||
return 1;
|
1,
|
||||||
|
format!("invalid date {}", form.quote()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let form = form[1..].to_string();
|
let form = form[1..].to_string();
|
||||||
Format::Custom(form)
|
Format::Custom(form)
|
||||||
|
@ -176,8 +182,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let set_to = match matches.value_of(OPT_SET).map(parse_date) {
|
let set_to = match matches.value_of(OPT_SET).map(parse_date) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(Err((input, _err))) => {
|
Some(Err((input, _err))) => {
|
||||||
show_error!("invalid date {}", input.quote());
|
return Err(USimpleError::new(
|
||||||
return 1;
|
1,
|
||||||
|
format!("invalid date {}", input.quote()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Some(Ok(date)) => Some(date),
|
Some(Ok(date)) => Some(date),
|
||||||
};
|
};
|
||||||
|
@ -241,14 +249,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let formatted = date.format(format_string).to_string().replace("%f", "%N");
|
let formatted = date.format(format_string).to_string().replace("%f", "%N");
|
||||||
println!("{}", formatted);
|
println!("{}", formatted);
|
||||||
}
|
}
|
||||||
Err((input, _err)) => {
|
Err((input, _err)) => show_error!("invalid date {}", input.quote()),
|
||||||
show_error!("invalid date {}", input.quote());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
@ -348,20 +354,24 @@ fn parse_date<S: AsRef<str> + Clone>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(unix, windows)))]
|
#[cfg(not(any(unix, windows)))]
|
||||||
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
|
fn set_system_datetime(_date: DateTime<Utc>) -> UResult<()> {
|
||||||
unimplemented!("setting date not implemented (unsupported target)");
|
unimplemented!("setting date not implemented (unsupported target)");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
|
fn set_system_datetime(_date: DateTime<Utc>) -> UResult<()> {
|
||||||
show_error!("setting the date is not supported by macOS");
|
Err(USimpleError::new(
|
||||||
1
|
1,
|
||||||
|
"setting the date is not supported by macOS".to_string(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
|
fn set_system_datetime(_date: DateTime<Utc>) -> UResult<()> {
|
||||||
show_error!("setting the date is not supported by Redox");
|
Err(USimpleError::new(
|
||||||
1
|
1,
|
||||||
|
"setting the date is not supported by Redox".to_string(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
|
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
|
||||||
|
@ -370,7 +380,7 @@ fn set_system_datetime(_date: DateTime<Utc>) -> i32 {
|
||||||
/// https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html
|
/// https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/fn.clock_settime.html
|
||||||
/// https://linux.die.net/man/3/clock_settime
|
/// https://linux.die.net/man/3/clock_settime
|
||||||
/// https://www.gnu.org/software/libc/manual/html_node/Time-Types.html
|
/// https://www.gnu.org/software/libc/manual/html_node/Time-Types.html
|
||||||
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
|
fn set_system_datetime(date: DateTime<Utc>) -> UResult<()> {
|
||||||
let timespec = timespec {
|
let timespec = timespec {
|
||||||
tv_sec: date.timestamp() as _,
|
tv_sec: date.timestamp() as _,
|
||||||
tv_nsec: date.timestamp_subsec_nanos() as _,
|
tv_nsec: date.timestamp_subsec_nanos() as _,
|
||||||
|
@ -379,11 +389,9 @@ fn set_system_datetime(date: DateTime<Utc>) -> i32 {
|
||||||
let result = unsafe { clock_settime(CLOCK_REALTIME, ×pec) };
|
let result = unsafe { clock_settime(CLOCK_REALTIME, ×pec) };
|
||||||
|
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
let error = std::io::Error::last_os_error();
|
Err(std::io::Error::last_os_error().map_err_context(|| "cannot set date".to_string()))
|
||||||
show_error!("cannot set date: {}", error);
|
|
||||||
error.raw_os_error().unwrap()
|
|
||||||
} else {
|
} else {
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +400,7 @@ fn set_system_datetime(date: DateTime<Utc>) -> i32 {
|
||||||
/// See here for more:
|
/// See here for more:
|
||||||
/// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-setsystemtime
|
/// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-setsystemtime
|
||||||
/// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
/// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
||||||
fn set_system_datetime(date: DateTime<Utc>) -> i32 {
|
fn set_system_datetime(date: DateTime<Utc>) -> UResult<()> {
|
||||||
let system_time = SYSTEMTIME {
|
let system_time = SYSTEMTIME {
|
||||||
wYear: date.year() as WORD,
|
wYear: date.year() as WORD,
|
||||||
wMonth: date.month() as WORD,
|
wMonth: date.month() as WORD,
|
||||||
|
@ -409,10 +417,8 @@ fn set_system_datetime(date: DateTime<Utc>) -> i32 {
|
||||||
let result = unsafe { SetSystemTime(&system_time) };
|
let result = unsafe { SetSystemTime(&system_time) };
|
||||||
|
|
||||||
if result == 0 {
|
if result == 0 {
|
||||||
let error = std::io::Error::last_os_error();
|
Err(std::io::Error::last_os_error().map_err_context(|| "cannot set date".to_string()))
|
||||||
show_error!("cannot set date: {}", error);
|
|
||||||
error.raw_os_error().unwrap()
|
|
||||||
} else {
|
} else {
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,12 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDOs) ncount routput
|
// spell-checker:ignore (ToDOs) ncount routput
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
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;
|
||||||
|
use uucore::display::Quotable;
|
||||||
|
use uucore::error::{FromIo, UResult, USimpleError};
|
||||||
use uucore::InvalidEncodingHandling;
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
const TAB_WIDTH: usize = 8;
|
const TAB_WIDTH: usize = 8;
|
||||||
|
@ -30,7 +29,8 @@ mod options {
|
||||||
pub const FILE: &str = "file";
|
pub const FILE: &str = "file";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args
|
let args = args
|
||||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
.accept_any();
|
.accept_any();
|
||||||
|
@ -46,10 +46,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
let width = match poss_width {
|
let width = match poss_width {
|
||||||
Some(inp_width) => match inp_width.parse::<usize>() {
|
Some(inp_width) => inp_width.parse::<usize>().map_err(|e| {
|
||||||
Ok(width) => width,
|
USimpleError::new(
|
||||||
Err(e) => crash!(1, "illegal width value (\"{}\"): {}", inp_width, e),
|
1,
|
||||||
},
|
format!("illegal width value ({}): {}", inp_width.quote(), e),
|
||||||
|
)
|
||||||
|
})?,
|
||||||
None => 80,
|
None => 80,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,9 +60,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
None => vec!["-".to_owned()],
|
None => vec!["-".to_owned()],
|
||||||
};
|
};
|
||||||
|
|
||||||
fold(files, bytes, spaces, width);
|
fold(files, bytes, spaces, width)
|
||||||
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
@ -110,7 +110,7 @@ fn handle_obsolete(args: &[String]) -> (Vec<String>, Option<String>) {
|
||||||
(args.to_vec(), None)
|
(args.to_vec(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold(filenames: Vec<String>, bytes: bool, spaces: bool, width: usize) {
|
fn fold(filenames: Vec<String>, bytes: bool, spaces: bool, width: usize) -> UResult<()> {
|
||||||
for filename in &filenames {
|
for filename in &filenames {
|
||||||
let filename: &str = filename;
|
let filename: &str = filename;
|
||||||
let mut stdin_buf;
|
let mut stdin_buf;
|
||||||
|
@ -119,16 +119,17 @@ fn fold(filenames: Vec<String>, bytes: bool, spaces: bool, width: usize) {
|
||||||
stdin_buf = stdin();
|
stdin_buf = stdin();
|
||||||
&mut stdin_buf as &mut dyn Read
|
&mut stdin_buf as &mut dyn Read
|
||||||
} else {
|
} else {
|
||||||
file_buf = crash_if_err!(1, File::open(Path::new(filename)));
|
file_buf = File::open(Path::new(filename)).map_err_context(|| filename.to_string())?;
|
||||||
&mut file_buf as &mut dyn Read
|
&mut file_buf as &mut dyn Read
|
||||||
});
|
});
|
||||||
|
|
||||||
if bytes {
|
if bytes {
|
||||||
fold_file_bytewise(buffer, spaces, width);
|
fold_file_bytewise(buffer, spaces, width)?;
|
||||||
} else {
|
} else {
|
||||||
fold_file(buffer, spaces, width);
|
fold_file(buffer, spaces, width)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fold `file` to fit `width` (number of columns), counting all characters as
|
/// Fold `file` to fit `width` (number of columns), counting all characters as
|
||||||
|
@ -139,11 +140,15 @@ fn fold(filenames: Vec<String>, bytes: bool, spaces: bool, width: usize) {
|
||||||
/// to all other characters in the stream.
|
/// to all other characters in the stream.
|
||||||
///
|
///
|
||||||
/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
|
/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
|
||||||
fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) {
|
fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> UResult<()> {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(0) = file.read_line(&mut line) {
|
if file
|
||||||
|
.read_line(&mut line)
|
||||||
|
.map_err_context(|| "failed to read line".to_string())?
|
||||||
|
== 0
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +195,8 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
|
||||||
|
|
||||||
line.truncate(0);
|
line.truncate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fold `file` to fit `width` (number of columns).
|
/// Fold `file` to fit `width` (number of columns).
|
||||||
|
@ -200,7 +207,7 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
|
||||||
///
|
///
|
||||||
/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
|
/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) {
|
fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> UResult<()> {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
let mut col_count = 0;
|
let mut col_count = 0;
|
||||||
|
@ -230,7 +237,11 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(0) = file.read_line(&mut line) {
|
if file
|
||||||
|
.read_line(&mut line)
|
||||||
|
.map_err_context(|| "failed to read line".to_string())?
|
||||||
|
== 0
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,4 +292,6 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) {
|
||||||
|
|
||||||
line.truncate(0);
|
line.truncate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,12 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) corasick memchr
|
// spell-checker:ignore (ToDO) corasick memchr
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, BufRead, BufReader, Read};
|
use std::io::{stdin, BufRead, BufReader, Read};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use uucore::error::{FromIo, UResult, USimpleError};
|
||||||
use uucore::InvalidEncodingHandling;
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
mod helper;
|
mod helper;
|
||||||
|
@ -83,7 +81,8 @@ pub mod options {
|
||||||
pub const NUMBER_WIDTH: &str = "number-width";
|
pub const NUMBER_WIDTH: &str = "number-width";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args
|
let args = args
|
||||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
.accept_any();
|
.accept_any();
|
||||||
|
@ -109,11 +108,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
// program if some options could not successfully be parsed.
|
// program if some options could not successfully be parsed.
|
||||||
let parse_errors = helper::parse_options(&mut settings, &matches);
|
let parse_errors = helper::parse_options(&mut settings, &matches);
|
||||||
if !parse_errors.is_empty() {
|
if !parse_errors.is_empty() {
|
||||||
show_error!("Invalid arguments supplied.");
|
return Err(USimpleError::new(
|
||||||
for message in &parse_errors {
|
1,
|
||||||
println!("{}", message);
|
format!("Invalid arguments supplied.\n{}", parse_errors.join("\n")),
|
||||||
}
|
));
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut read_stdin = false;
|
let mut read_stdin = false;
|
||||||
|
@ -130,16 +128,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let path = Path::new(file);
|
let path = Path::new(file);
|
||||||
let reader = File::open(path).unwrap();
|
let reader = File::open(path).map_err_context(|| file.to_string())?;
|
||||||
let mut buffer = BufReader::new(reader);
|
let mut buffer = BufReader::new(reader);
|
||||||
nl(&mut buffer, &settings);
|
nl(&mut buffer, &settings)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if read_stdin {
|
if read_stdin {
|
||||||
let mut buffer = BufReader::new(stdin());
|
let mut buffer = BufReader::new(stdin());
|
||||||
nl(&mut buffer, &settings);
|
nl(&mut buffer, &settings)?;
|
||||||
}
|
}
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
@ -227,7 +225,7 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nl implements the main functionality for an individual buffer.
|
// nl implements the main functionality for an individual buffer.
|
||||||
fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) {
|
fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> UResult<()> {
|
||||||
let regexp: regex::Regex = regex::Regex::new(r".?").unwrap();
|
let regexp: regex::Regex = regex::Regex::new(r".?").unwrap();
|
||||||
let mut line_no = settings.starting_line_number;
|
let mut line_no = settings.starting_line_number;
|
||||||
// The current line number's width as a string. Using to_string is inefficient
|
// The current line number's width as a string. Using to_string is inefficient
|
||||||
|
@ -248,7 +246,8 @@ fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) {
|
||||||
_ => ®exp,
|
_ => ®exp,
|
||||||
};
|
};
|
||||||
let mut line_filter: fn(&str, ®ex::Regex) -> bool = pass_regex;
|
let mut line_filter: fn(&str, ®ex::Regex) -> bool = pass_regex;
|
||||||
for mut l in reader.lines().map(|r| r.unwrap()) {
|
for l in reader.lines() {
|
||||||
|
let mut l = l.map_err_context(|| "could not read line".to_string())?;
|
||||||
// Sanitize the string. We want to print the newline ourselves.
|
// Sanitize the string. We want to print the newline ourselves.
|
||||||
if l.ends_with('\n') {
|
if l.ends_with('\n') {
|
||||||
l.pop();
|
l.pop();
|
||||||
|
@ -372,6 +371,7 @@ fn nl<T: Read>(reader: &mut BufReader<T>, settings: &Settings) {
|
||||||
line_no_width += 1;
|
line_no_width += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pass_regex(line: &str, re: ®ex::Regex) -> bool {
|
fn pass_regex(line: &str, re: ®ex::Regex) -> bool {
|
||||||
|
|
|
@ -7,11 +7,10 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr threadstr sysconf
|
// spell-checker:ignore (ToDO) NPROCESSORS nprocs numstr threadstr sysconf
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use uucore::display::Quotable;
|
||||||
|
use uucore::error::{UResult, USimpleError};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub const _SC_NPROCESSORS_CONF: libc::c_int = 83;
|
pub const _SC_NPROCESSORS_CONF: libc::c_int = 83;
|
||||||
|
@ -31,7 +30,8 @@ fn usage() -> String {
|
||||||
format!("{0} [OPTIONS]...", uucore::execution_phrase())
|
format!("{0} [OPTIONS]...", uucore::execution_phrase())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let usage = usage();
|
let usage = usage();
|
||||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||||
|
|
||||||
|
@ -39,8 +39,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
Some(numstr) => match numstr.parse() {
|
Some(numstr) => match numstr.parse() {
|
||||||
Ok(num) => num,
|
Ok(num) => num,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
show_error!("\"{}\" is not a valid number: {}", numstr, e);
|
return Err(USimpleError::new(
|
||||||
return 1;
|
1,
|
||||||
|
format!("{} is not a valid number: {}", numstr.quote(), e),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => 0,
|
None => 0,
|
||||||
|
@ -66,7 +68,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
cores -= ignore;
|
cores -= ignore;
|
||||||
}
|
}
|
||||||
println!("{}", cores);
|
println!("{}", cores);
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) cmdline evec seps rvec fdata
|
// spell-checker:ignore (ToDO) cmdline evec seps rvec fdata
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
|
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
|
use uucore::error::{FromIo, UResult, USimpleError};
|
||||||
use uucore::InvalidEncodingHandling;
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
enum Mode {
|
enum Mode {
|
||||||
|
@ -52,7 +50,8 @@ mod options {
|
||||||
pub static FILE: &str = "file";
|
pub static FILE: &str = "file";
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let args = args
|
let args = args
|
||||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||||
.accept_any();
|
.accept_any();
|
||||||
|
@ -65,7 +64,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
match parse_range(range) {
|
match parse_range(range) {
|
||||||
Ok(m) => Mode::InputRange(m),
|
Ok(m) => Mode::InputRange(m),
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
crash!(1, "{}", msg);
|
return Err(USimpleError::new(1, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -77,8 +76,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
Some(count) => match count.parse::<usize>() {
|
Some(count) => match count.parse::<usize>() {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
show_error!("invalid line count: {}", count.quote());
|
return Err(USimpleError::new(
|
||||||
return 1;
|
1,
|
||||||
|
format!("invalid line count: {}", count.quote()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => std::usize::MAX,
|
None => std::usize::MAX,
|
||||||
|
@ -97,22 +98,22 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
Mode::Echo(args) => {
|
Mode::Echo(args) => {
|
||||||
let mut evec = args.iter().map(String::as_bytes).collect::<Vec<_>>();
|
let mut evec = args.iter().map(String::as_bytes).collect::<Vec<_>>();
|
||||||
find_seps(&mut evec, options.sep);
|
find_seps(&mut evec, options.sep);
|
||||||
shuf_bytes(&mut evec, options);
|
shuf_bytes(&mut evec, options)?;
|
||||||
}
|
}
|
||||||
Mode::InputRange((b, e)) => {
|
Mode::InputRange((b, e)) => {
|
||||||
let rvec = (b..e).map(|x| format!("{}", x)).collect::<Vec<String>>();
|
let rvec = (b..e).map(|x| format!("{}", x)).collect::<Vec<String>>();
|
||||||
let mut rvec = rvec.iter().map(String::as_bytes).collect::<Vec<&[u8]>>();
|
let mut rvec = rvec.iter().map(String::as_bytes).collect::<Vec<&[u8]>>();
|
||||||
shuf_bytes(&mut rvec, options);
|
shuf_bytes(&mut rvec, options)?;
|
||||||
}
|
}
|
||||||
Mode::Default(filename) => {
|
Mode::Default(filename) => {
|
||||||
let fdata = read_input_file(&filename);
|
let fdata = read_input_file(&filename)?;
|
||||||
let mut fdata = vec![&fdata[..]];
|
let mut fdata = vec![&fdata[..]];
|
||||||
find_seps(&mut fdata, options.sep);
|
find_seps(&mut fdata, options.sep);
|
||||||
shuf_bytes(&mut fdata, options);
|
shuf_bytes(&mut fdata, options)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
@ -180,22 +181,20 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
.arg(Arg::with_name(options::FILE).takes_value(true))
|
.arg(Arg::with_name(options::FILE).takes_value(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_input_file(filename: &str) -> Vec<u8> {
|
fn read_input_file(filename: &str) -> UResult<Vec<u8>> {
|
||||||
let mut file = BufReader::new(if filename == "-" {
|
let mut file = BufReader::new(if filename == "-" {
|
||||||
Box::new(stdin()) as Box<dyn Read>
|
Box::new(stdin()) as Box<dyn Read>
|
||||||
} else {
|
} else {
|
||||||
match File::open(filename) {
|
let file = File::open(filename)
|
||||||
Ok(f) => Box::new(f) as Box<dyn Read>,
|
.map_err_context(|| format!("failed to open {}", filename.quote()))?;
|
||||||
Err(e) => crash!(1, "failed to open {}: {}", filename.quote(), e),
|
Box::new(file) as Box<dyn Read>
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
if let Err(e) = file.read_to_end(&mut data) {
|
file.read_to_end(&mut data)
|
||||||
crash!(1, "failed reading {}: {}", filename.quote(), e)
|
.map_err_context(|| format!("failed reading {}", filename.quote()))?;
|
||||||
};
|
|
||||||
|
|
||||||
data
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_seps(data: &mut Vec<&[u8]>, sep: u8) {
|
fn find_seps(data: &mut Vec<&[u8]>, sep: u8) {
|
||||||
|
@ -231,22 +230,22 @@ fn find_seps(data: &mut Vec<&[u8]>, sep: u8) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) {
|
fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) -> UResult<()> {
|
||||||
let mut output = BufWriter::new(match opts.output {
|
let mut output = BufWriter::new(match opts.output {
|
||||||
None => Box::new(stdout()) as Box<dyn Write>,
|
None => Box::new(stdout()) as Box<dyn Write>,
|
||||||
Some(s) => match File::create(&s[..]) {
|
Some(s) => {
|
||||||
Ok(f) => Box::new(f) as Box<dyn Write>,
|
let file = File::create(&s[..])
|
||||||
Err(e) => crash!(1, "failed to open {} for writing: {}", s.quote(), e),
|
.map_err_context(|| format!("failed to open {} for writing", s.quote()))?;
|
||||||
},
|
Box::new(file) as Box<dyn Write>
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut rng = match opts.random_source {
|
let mut rng = match opts.random_source {
|
||||||
Some(r) => WrappedRng::RngFile(rand::rngs::adapter::ReadRng::new(
|
Some(r) => {
|
||||||
match File::open(&r[..]) {
|
let file = File::open(&r[..])
|
||||||
Ok(f) => f,
|
.map_err_context(|| format!("failed to open random source {}", r.quote()))?;
|
||||||
Err(e) => crash!(1, "failed to open random source {}: {}", r.quote(), e),
|
WrappedRng::RngFile(rand::rngs::adapter::ReadRng::new(file))
|
||||||
},
|
}
|
||||||
)),
|
|
||||||
None => WrappedRng::RngDefault(rand::thread_rng()),
|
None => WrappedRng::RngDefault(rand::thread_rng()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -268,10 +267,10 @@ fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) {
|
||||||
// write the randomly chosen value and the separator
|
// write the randomly chosen value and the separator
|
||||||
output
|
output
|
||||||
.write_all(input[r])
|
.write_all(input[r])
|
||||||
.unwrap_or_else(|e| crash!(1, "write failed: {}", e));
|
.map_err_context(|| "write failed".to_string())?;
|
||||||
output
|
output
|
||||||
.write_all(&[opts.sep])
|
.write_all(&[opts.sep])
|
||||||
.unwrap_or_else(|e| crash!(1, "write failed: {}", e));
|
.map_err_context(|| "write failed".to_string())?;
|
||||||
|
|
||||||
// if we do not allow repeats, remove the chosen value from the input vector
|
// if we do not allow repeats, remove the chosen value from the input vector
|
||||||
if !opts.repeat {
|
if !opts.repeat {
|
||||||
|
@ -284,6 +283,7 @@ fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) {
|
||||||
|
|
||||||
count -= 1;
|
count -= 1;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_range(input_range: &str) -> Result<(usize, usize), String> {
|
fn parse_range(input_range: &str) -> Result<(usize, usize), String> {
|
||||||
|
|
|
@ -10,11 +10,9 @@
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv
|
// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use platform_info::*;
|
use platform_info::*;
|
||||||
|
use uucore::error::{FromIo, UResult};
|
||||||
|
|
||||||
const ABOUT: &str = "Print certain system information. With no OPTION, same as -s.";
|
const ABOUT: &str = "Print certain system information. With no OPTION, same as -s.";
|
||||||
|
|
||||||
|
@ -49,11 +47,13 @@ const HOST_OS: &str = "Fuchsia";
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
const HOST_OS: &str = "Redox";
|
const HOST_OS: &str = "Redox";
|
||||||
|
|
||||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
#[uucore_procs::gen_uumain]
|
||||||
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let usage = format!("{} [OPTION]...", uucore::execution_phrase());
|
let usage = format!("{} [OPTION]...", uucore::execution_phrase());
|
||||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||||
|
|
||||||
let uname = crash_if_err!(1, PlatformInfo::new());
|
let uname =
|
||||||
|
PlatformInfo::new().map_err_context(|| "failed to create PlatformInfo".to_string())?;
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
let all = matches.is_present(options::ALL);
|
let all = matches.is_present(options::ALL);
|
||||||
|
@ -115,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
}
|
}
|
||||||
println!("{}", output.trim_end());
|
println!("{}", output.trim_end());
|
||||||
|
|
||||||
0
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app() -> App<'static, 'static> {
|
pub fn uu_app() -> App<'static, 'static> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue