mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
Update message quoting and filename printing
This commit is contained in:
parent
60df3c6b7c
commit
259f18fcab
91 changed files with 777 additions and 550 deletions
|
@ -9,6 +9,8 @@ bytewise
|
|||
canonicalization
|
||||
canonicalize
|
||||
canonicalizing
|
||||
codepoint
|
||||
codepoints
|
||||
colorizable
|
||||
colorize
|
||||
coprime
|
||||
|
|
|
@ -10,10 +10,12 @@ use clap::Arg;
|
|||
use clap::Shell;
|
||||
use std::cmp;
|
||||
use std::collections::hash_map::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::ffi::OsString;
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
|
@ -76,13 +78,21 @@ fn main() {
|
|||
|
||||
// 0th argument equals util name?
|
||||
if let Some(util_os) = util_name {
|
||||
let util = util_os.as_os_str().to_string_lossy();
|
||||
fn not_found(util: &OsStr) -> ! {
|
||||
println!("{}: function/utility not found", util.maybe_quote());
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let util = match util_os.to_str() {
|
||||
Some(util) => util,
|
||||
None => not_found(&util_os),
|
||||
};
|
||||
|
||||
if util == "completion" {
|
||||
gen_completions(args, utils);
|
||||
}
|
||||
|
||||
match utils.get(&util[..]) {
|
||||
match utils.get(util) {
|
||||
Some(&(uumain, _)) => {
|
||||
process::exit(uumain((vec![util_os].into_iter()).chain(args)));
|
||||
}
|
||||
|
@ -90,9 +100,12 @@ fn main() {
|
|||
if util == "--help" || util == "-h" {
|
||||
// see if they want help on a specific util
|
||||
if let Some(util_os) = args.next() {
|
||||
let util = util_os.as_os_str().to_string_lossy();
|
||||
let util = match util_os.to_str() {
|
||||
Some(util) => util,
|
||||
None => not_found(&util_os),
|
||||
};
|
||||
|
||||
match utils.get(&util[..]) {
|
||||
match utils.get(util) {
|
||||
Some(&(uumain, _)) => {
|
||||
let code = uumain(
|
||||
(vec![util_os, OsString::from("--help")].into_iter())
|
||||
|
@ -101,17 +114,13 @@ fn main() {
|
|||
io::stdout().flush().expect("could not flush stdout");
|
||||
process::exit(code);
|
||||
}
|
||||
None => {
|
||||
println!("{}: function/utility not found", util);
|
||||
process::exit(1);
|
||||
}
|
||||
None => not_found(&util_os),
|
||||
}
|
||||
}
|
||||
usage(&utils, binary_as_util);
|
||||
process::exit(0);
|
||||
} else {
|
||||
println!("{}: function/utility not found", util);
|
||||
process::exit(1);
|
||||
not_found(&util_os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
use std::io::{stdout, Read, Write};
|
||||
|
||||
use uucore::display::Quotable;
|
||||
use uucore::encoding::{wrap_print, Data, Format};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
|
@ -40,8 +41,9 @@ impl Config {
|
|||
let name = values.next().unwrap();
|
||||
if let Some(extra_op) = values.next() {
|
||||
return Err(format!(
|
||||
"extra operand '{}'\nTry '{} --help' for more information.",
|
||||
extra_op, app_name
|
||||
"extra operand {}\nTry '{} --help' for more information.",
|
||||
extra_op.quote(),
|
||||
app_name
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -49,7 +51,7 @@ impl Config {
|
|||
None
|
||||
} else {
|
||||
if !Path::exists(Path::new(name)) {
|
||||
return Err(format!("{}: No such file or directory", name));
|
||||
return Err(format!("{}: No such file or directory", name.maybe_quote()));
|
||||
}
|
||||
Some(name.to_owned())
|
||||
}
|
||||
|
@ -61,7 +63,7 @@ impl Config {
|
|||
.value_of(options::WRAP)
|
||||
.map(|num| {
|
||||
num.parse::<usize>()
|
||||
.map_err(|_| format!("invalid wrap size: '{}'", num))
|
||||
.map_err(|_| format!("invalid wrap size: {}", num.quote()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::fs::{metadata, File};
|
||||
use std::io::{self, Read, Write};
|
||||
use thiserror::Error;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::UResult;
|
||||
|
||||
#[cfg(unix)]
|
||||
|
@ -386,7 +387,7 @@ fn cat_files(files: Vec<String>, options: &OutputOptions) -> UResult<()> {
|
|||
|
||||
for path in &files {
|
||||
if let Err(err) = cat_path(path, options, &mut state, &out_info) {
|
||||
error_messages.push(format!("{}: {}", path, err));
|
||||
error_messages.push(format!("{}: {}", path.maybe_quote(), err));
|
||||
}
|
||||
}
|
||||
if state.skipped_carriage_return {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#![allow(clippy::upper_case_acronyms)]
|
||||
|
||||
use uucore::{show_error, show_usage_error, show_warning};
|
||||
use uucore::{display::Quotable, show_error, show_usage_error, show_warning};
|
||||
|
||||
use clap::{App, Arg};
|
||||
use selinux::{OpaqueSecurityContext, SecurityContext};
|
||||
|
@ -111,13 +111,13 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
Ok(context) => context,
|
||||
|
||||
Err(_r) => {
|
||||
show_error!("Invalid security context '{}'.", context.to_string_lossy());
|
||||
show_error!("Invalid security context {}.", context.quote());
|
||||
return libc::EXIT_FAILURE;
|
||||
}
|
||||
};
|
||||
|
||||
if SecurityContext::from_c_str(&c_context, false).check() == Some(false) {
|
||||
show_error!("Invalid security context '{}'.", context.to_string_lossy());
|
||||
show_error!("Invalid security context {}.", context.quote());
|
||||
return libc::EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -564,7 +564,7 @@ fn process_file(
|
|||
println!(
|
||||
"{}: Changing security context of: {}",
|
||||
uucore::util_name(),
|
||||
file_full_name.to_string_lossy()
|
||||
file_full_name.quote()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -699,9 +699,9 @@ fn root_dev_ino_warn(dir_name: &Path) {
|
|||
);
|
||||
} else {
|
||||
show_warning!(
|
||||
"It is dangerous to operate recursively on '{}' (same as '/'). \
|
||||
"It is dangerous to operate recursively on {} (same as '/'). \
|
||||
Use --{} to override this failsafe.",
|
||||
dir_name.to_string_lossy(),
|
||||
dir_name.quote(),
|
||||
options::preserve_root::NO_PRESERVE_ROOT,
|
||||
);
|
||||
}
|
||||
|
@ -726,8 +726,8 @@ fn emit_cycle_warning(file_name: &Path) {
|
|||
"Circular directory structure.\n\
|
||||
This almost certainly means that you have a corrupted file system.\n\
|
||||
NOTIFY YOUR SYSTEM MANAGER.\n\
|
||||
The following directory is part of the cycle '{}'.",
|
||||
file_name.display()
|
||||
The following directory is part of the cycle {}.",
|
||||
file_name.quote()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ use std::ffi::OsString;
|
|||
use std::fmt::Write;
|
||||
use std::io;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
|
@ -30,7 +32,7 @@ pub(crate) enum Error {
|
|||
source: io::Error,
|
||||
},
|
||||
|
||||
#[error("{operation} failed on '{}'", .operand1.to_string_lossy())]
|
||||
#[error("{operation} failed on {}", .operand1.quote())]
|
||||
Io1 {
|
||||
operation: &'static str,
|
||||
operand1: OsString,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
use uucore::display::Quotable;
|
||||
pub use uucore::entries;
|
||||
use uucore::error::{FromIo, UResult, USimpleError};
|
||||
use uucore::perms::{chown_base, options, IfFrom};
|
||||
|
@ -32,7 +33,7 @@ fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option<u32>, Option<u32>,
|
|||
let dest_gid = if let Some(file) = matches.value_of(options::REFERENCE) {
|
||||
fs::metadata(&file)
|
||||
.map(|meta| Some(meta.gid()))
|
||||
.map_err_context(|| format!("failed to get attributes of '{}'", file))?
|
||||
.map_err_context(|| format!("failed to get attributes of {}", file.quote()))?
|
||||
} else {
|
||||
let group = matches.value_of(options::ARG_GROUP).unwrap_or_default();
|
||||
if group.is_empty() {
|
||||
|
@ -40,7 +41,12 @@ fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option<u32>, Option<u32>,
|
|||
} else {
|
||||
match entries::grp2gid(group) {
|
||||
Ok(g) => Some(g),
|
||||
_ => return Err(USimpleError::new(1, format!("invalid group: '{}'", group))),
|
||||
_ => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("invalid group: {}", group.quote()),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::fs;
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::fs::display_permissions_unix;
|
||||
use uucore::libc::mode_t;
|
||||
#[cfg(not(windows))]
|
||||
|
@ -75,7 +76,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.value_of(options::REFERENCE)
|
||||
.and_then(|fref| match fs::metadata(fref) {
|
||||
Ok(meta) => Some(meta.mode()),
|
||||
Err(err) => crash!(1, "cannot stat attributes of '{}': {}", fref, err),
|
||||
Err(err) => crash!(1, "cannot stat attributes of {}: {}", fref.quote(), err),
|
||||
});
|
||||
let modes = matches.value_of(options::MODE).unwrap(); // should always be Some because required
|
||||
let cmode = if mode_had_minus_prefix {
|
||||
|
@ -223,21 +224,24 @@ impl Chmoder {
|
|||
if !file.exists() {
|
||||
if is_symlink(file) {
|
||||
println!(
|
||||
"failed to change mode of '{}' from 0000 (---------) to 0000 (---------)",
|
||||
filename
|
||||
"failed to change mode of {} from 0000 (---------) to 0000 (---------)",
|
||||
filename.quote()
|
||||
);
|
||||
if !self.quiet {
|
||||
show_error!("cannot operate on dangling symlink '{}'", filename);
|
||||
show_error!("cannot operate on dangling symlink {}", filename.quote());
|
||||
}
|
||||
} else if !self.quiet {
|
||||
show_error!("cannot access '{}': No such file or directory", filename);
|
||||
show_error!(
|
||||
"cannot access {}: No such file or directory",
|
||||
filename.quote()
|
||||
);
|
||||
}
|
||||
return Err(1);
|
||||
}
|
||||
if self.recursive && self.preserve_root && filename == "/" {
|
||||
show_error!(
|
||||
"it is dangerous to operate recursively on '{}'\nuse --no-preserve-root to override this failsafe",
|
||||
filename
|
||||
"it is dangerous to operate recursively on {}\nuse --no-preserve-root to override this failsafe",
|
||||
filename.quote()
|
||||
);
|
||||
return Err(1);
|
||||
}
|
||||
|
@ -270,15 +274,17 @@ impl Chmoder {
|
|||
if is_symlink(file) {
|
||||
if self.verbose {
|
||||
println!(
|
||||
"neither symbolic link '{}' nor referent has been changed",
|
||||
file.display()
|
||||
"neither symbolic link {} nor referent has been changed",
|
||||
file.quote()
|
||||
);
|
||||
}
|
||||
return Ok(());
|
||||
} else if err.kind() == std::io::ErrorKind::PermissionDenied {
|
||||
show_error!("'{}': Permission denied", file.display());
|
||||
// These two filenames would normally be conditionally
|
||||
// quoted, but GNU's tests expect them to always be quoted
|
||||
show_error!("{}: Permission denied", file.quote());
|
||||
} else {
|
||||
show_error!("'{}': {}", file.display(), err);
|
||||
show_error!("{}: {}", file.quote(), err);
|
||||
}
|
||||
return Err(1);
|
||||
}
|
||||
|
@ -325,7 +331,7 @@ impl Chmoder {
|
|||
if (new_mode & !naively_expected_new_mode) != 0 {
|
||||
show_error!(
|
||||
"{}: new permissions are {}, not {}",
|
||||
file.display(),
|
||||
file.maybe_quote(),
|
||||
display_permissions_unix(new_mode as mode_t, false),
|
||||
display_permissions_unix(naively_expected_new_mode as mode_t, false)
|
||||
);
|
||||
|
@ -342,8 +348,8 @@ impl Chmoder {
|
|||
if fperm == mode {
|
||||
if self.verbose && !self.changes {
|
||||
println!(
|
||||
"mode of '{}' retained as {:04o} ({})",
|
||||
file.display(),
|
||||
"mode of {} retained as {:04o} ({})",
|
||||
file.quote(),
|
||||
fperm,
|
||||
display_permissions_unix(fperm as mode_t, false),
|
||||
);
|
||||
|
@ -355,8 +361,8 @@ impl Chmoder {
|
|||
}
|
||||
if self.verbose {
|
||||
println!(
|
||||
"failed to change mode of file '{}' from {:04o} ({}) to {:04o} ({})",
|
||||
file.display(),
|
||||
"failed to change mode of file {} from {:04o} ({}) to {:04o} ({})",
|
||||
file.quote(),
|
||||
fperm,
|
||||
display_permissions_unix(fperm as mode_t, false),
|
||||
mode,
|
||||
|
@ -367,8 +373,8 @@ impl Chmoder {
|
|||
} else {
|
||||
if self.verbose || self.changes {
|
||||
println!(
|
||||
"mode of '{}' changed from {:04o} ({}) to {:04o} ({})",
|
||||
file.display(),
|
||||
"mode of {} changed from {:04o} ({}) to {:04o} ({})",
|
||||
file.quote(),
|
||||
fperm,
|
||||
display_permissions_unix(fperm as mode_t, false),
|
||||
mode,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
use uucore::display::Quotable;
|
||||
pub use uucore::entries::{self, Group, Locate, Passwd};
|
||||
use uucore::perms::{chown_base, options, IfFrom};
|
||||
|
||||
|
@ -44,7 +45,7 @@ fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult<(Option<u32>, Optio
|
|||
let dest_gid: Option<u32>;
|
||||
if let Some(file) = matches.value_of(options::REFERENCE) {
|
||||
let meta = fs::metadata(&file)
|
||||
.map_err_context(|| format!("failed to get attributes of '{}'", file))?;
|
||||
.map_err_context(|| format!("failed to get attributes of {}", file.quote()))?;
|
||||
dest_gid = Some(meta.gid());
|
||||
dest_uid = Some(meta.uid());
|
||||
} else {
|
||||
|
@ -173,7 +174,7 @@ fn parse_spec(spec: &str) -> UResult<(Option<u32>, Option<u32>)> {
|
|||
let uid = if usr_only || usr_grp {
|
||||
Some(
|
||||
Passwd::locate(args[0])
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid user: '{}'", spec)))?
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid user: {}", spec.quote())))?
|
||||
.uid(),
|
||||
)
|
||||
} else {
|
||||
|
@ -182,7 +183,7 @@ fn parse_spec(spec: &str) -> UResult<(Option<u32>, Option<u32>)> {
|
|||
let gid = if grp_only || usr_grp {
|
||||
Some(
|
||||
Group::locate(args[1])
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid group: '{}'", spec)))?
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid group: {}", spec.quote())))?
|
||||
.gid(),
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -15,6 +15,7 @@ use std::ffi::CString;
|
|||
use std::io::Error;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
|
||||
use uucore::{entries, InvalidEncodingHandling};
|
||||
|
||||
|
@ -53,8 +54,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if !newroot.is_dir() {
|
||||
crash!(
|
||||
1,
|
||||
"cannot change root directory to `{}`: no such directory",
|
||||
newroot.display()
|
||||
"cannot change root directory to {}: no such directory",
|
||||
newroot.quote()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -170,7 +171,6 @@ fn set_context(root: &Path, options: &clap::ArgMatches) {
|
|||
}
|
||||
|
||||
fn enter_chroot(root: &Path) {
|
||||
let root_str = root.display();
|
||||
std::env::set_current_dir(root).unwrap();
|
||||
let err = unsafe {
|
||||
chroot(CString::new(".").unwrap().as_bytes_with_nul().as_ptr() as *const libc::c_char)
|
||||
|
@ -179,7 +179,7 @@ fn enter_chroot(root: &Path) {
|
|||
crash!(
|
||||
1,
|
||||
"cannot chroot to {}: {}",
|
||||
root_str,
|
||||
root.quote(),
|
||||
Error::last_os_error()
|
||||
)
|
||||
};
|
||||
|
@ -189,7 +189,7 @@ fn set_main_group(group: &str) {
|
|||
if !group.is_empty() {
|
||||
let group_id = match entries::grp2gid(group) {
|
||||
Ok(g) => g,
|
||||
_ => crash!(1, "no such group: {}", group),
|
||||
_ => crash!(1, "no such group: {}", group.maybe_quote()),
|
||||
};
|
||||
let err = unsafe { setgid(group_id) };
|
||||
if err != 0 {
|
||||
|
@ -234,7 +234,12 @@ fn set_user(user: &str) {
|
|||
let user_id = entries::usr2uid(user).unwrap();
|
||||
let err = unsafe { setuid(user_id as libc::uid_t) };
|
||||
if err != 0 {
|
||||
crash!(1, "cannot set user to {}: {}", user, Error::last_os_error())
|
||||
crash!(
|
||||
1,
|
||||
"cannot set user to {}: {}",
|
||||
user.maybe_quote(),
|
||||
Error::last_os_error()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::fs::File;
|
||||
use std::io::{self, stdin, BufReader, Read};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
// NOTE: CRC_TABLE_LEN *must* be <= 256 as we cast 0..CRC_TABLE_LEN to u8
|
||||
|
@ -191,7 +192,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
match cksum("-") {
|
||||
Ok((crc, size)) => println!("{} {}", crc, size),
|
||||
Err(err) => {
|
||||
show_error!("{}", err);
|
||||
show_error!("-: {}", err);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +204,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
match cksum(fname.as_ref()) {
|
||||
Ok((crc, size)) => println!("{} {} {}", crc, size, fname),
|
||||
Err(err) => {
|
||||
show_error!("'{}' {}", fname, err);
|
||||
show_error!("{}: {}", fname.maybe_quote(), err);
|
||||
exit_code = 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ extern crate quick_error;
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
#[cfg(windows)]
|
||||
use winapi::um::fileapi::CreateFileW;
|
||||
#[cfg(windows)]
|
||||
|
@ -541,8 +542,8 @@ impl FromStr for Attribute {
|
|||
"xattr" => Attribute::Xattr,
|
||||
_ => {
|
||||
return Err(Error::InvalidArgument(format!(
|
||||
"invalid attribute '{}'",
|
||||
value
|
||||
"invalid attribute {}",
|
||||
value.quote()
|
||||
)));
|
||||
}
|
||||
})
|
||||
|
@ -659,8 +660,8 @@ impl Options {
|
|||
"never" => ReflinkMode::Never,
|
||||
value => {
|
||||
return Err(Error::InvalidArgument(format!(
|
||||
"invalid argument '{}' for \'reflink\'",
|
||||
value
|
||||
"invalid argument {} for \'reflink\'",
|
||||
value.quote()
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
@ -832,7 +833,7 @@ fn copy(sources: &[Source], target: &TargetSlice, options: &Options) -> CopyResu
|
|||
let mut seen_sources = HashSet::with_capacity(sources.len());
|
||||
for source in sources {
|
||||
if seen_sources.contains(source) {
|
||||
show_warning!("source '{}' specified more than once", source.display());
|
||||
show_warning!("source {} specified more than once", source.quote());
|
||||
} else {
|
||||
let mut found_hard_link = false;
|
||||
if preserve_hard_links {
|
||||
|
@ -873,8 +874,8 @@ fn construct_dest_path(
|
|||
) -> CopyResult<PathBuf> {
|
||||
if options.no_target_dir && target.is_dir() {
|
||||
return Err(format!(
|
||||
"cannot overwrite directory '{}' with non-directory",
|
||||
target.display()
|
||||
"cannot overwrite directory {} with non-directory",
|
||||
target.quote()
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
@ -941,7 +942,7 @@ fn adjust_canonicalization(p: &Path) -> Cow<Path> {
|
|||
/// will not cause a short-circuit.
|
||||
fn copy_directory(root: &Path, target: &TargetSlice, options: &Options) -> CopyResult<()> {
|
||||
if !options.recursive {
|
||||
return Err(format!("omitting directory '{}'", root.display()).into());
|
||||
return Err(format!("omitting directory {}", root.quote()).into());
|
||||
}
|
||||
|
||||
// if no-dereference is enabled and this is a symlink, copy it as a file
|
||||
|
@ -1041,12 +1042,12 @@ impl OverwriteMode {
|
|||
match *self {
|
||||
OverwriteMode::NoClobber => Err(Error::NotAllFilesCopied),
|
||||
OverwriteMode::Interactive(_) => {
|
||||
if prompt_yes!("{}: overwrite {}? ", uucore::util_name(), path.display()) {
|
||||
if prompt_yes!("{}: overwrite {}? ", uucore::util_name(), path.quote()) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Skipped(format!(
|
||||
"Not overwriting {} at user request",
|
||||
path.display()
|
||||
path.quote()
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -1056,7 +1057,7 @@ impl OverwriteMode {
|
|||
}
|
||||
|
||||
fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResult<()> {
|
||||
let context = &*format!("'{}' -> '{}'", source.display().to_string(), dest.display());
|
||||
let context = &*format!("{} -> {}", source.quote(), dest.quote());
|
||||
let source_metadata = fs::symlink_metadata(source).context(context)?;
|
||||
match *attribute {
|
||||
Attribute::Mode => {
|
||||
|
@ -1152,7 +1153,7 @@ fn symlink_file(source: &Path, dest: &Path, context: &str) -> CopyResult<()> {
|
|||
}
|
||||
|
||||
fn context_for(src: &Path, dest: &Path) -> String {
|
||||
format!("'{}' -> '{}'", src.display(), dest.display())
|
||||
format!("{} -> {}", src.quote(), dest.quote())
|
||||
}
|
||||
|
||||
/// Implements a simple backup copy for the destination file.
|
||||
|
@ -1332,8 +1333,8 @@ fn copy_link(source: &Path, dest: &Path) -> CopyResult<()> {
|
|||
Some(name) => dest.join(name).into(),
|
||||
None => crash!(
|
||||
EXIT_ERR,
|
||||
"cannot stat '{}': No such file or directory",
|
||||
source.display()
|
||||
"cannot stat {}: No such file or directory",
|
||||
source.quote()
|
||||
),
|
||||
}
|
||||
} else {
|
||||
|
@ -1454,11 +1455,11 @@ fn copy_on_write_macos(
|
|||
pub fn verify_target_type(target: &Path, target_type: &TargetType) -> CopyResult<()> {
|
||||
match (target_type, target.is_dir()) {
|
||||
(&TargetType::Directory, false) => {
|
||||
Err(format!("target: '{}' is not a directory", target.display()).into())
|
||||
Err(format!("target: {} is not a directory", target.quote()).into())
|
||||
}
|
||||
(&TargetType::File, true) => Err(format!(
|
||||
"cannot overwrite directory '{}' with non-directory",
|
||||
target.display()
|
||||
"cannot overwrite directory {} with non-directory",
|
||||
target.quote()
|
||||
)
|
||||
.into()),
|
||||
_ => Ok(()),
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::{
|
|||
fs::{remove_file, File},
|
||||
io::{BufRead, BufWriter, Write},
|
||||
};
|
||||
use uucore::display::Quotable;
|
||||
|
||||
mod csplit_error;
|
||||
mod patterns;
|
||||
|
@ -734,7 +735,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let file = crash_if_err!(1, File::open(file_name));
|
||||
let file_metadata = crash_if_err!(1, file.metadata());
|
||||
if !file_metadata.is_file() {
|
||||
crash!(1, "'{}' is not a regular file", file_name);
|
||||
crash!(1, "{} is not a regular file", file_name.quote());
|
||||
}
|
||||
crash_if_err!(1, csplit(&options, patterns, BufReader::new(file)));
|
||||
};
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
use std::io;
|
||||
use thiserror::Error;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
/// Errors thrown by the csplit command
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CsplitError {
|
||||
#[error("IO error: {}", _0)]
|
||||
IoError(io::Error),
|
||||
#[error("'{}': line number out of range", _0)]
|
||||
#[error("{}: line number out of range", ._0.quote())]
|
||||
LineOutOfRange(String),
|
||||
#[error("'{}': line number out of range on repetition {}", _0, _1)]
|
||||
#[error("{}: line number out of range on repetition {}", ._0.quote(), _1)]
|
||||
LineOutOfRangeOnRepetition(String, usize),
|
||||
#[error("'{}': match not found", _0)]
|
||||
#[error("{}: match not found", ._0.quote())]
|
||||
MatchNotFound(String),
|
||||
#[error("'{}': match not found on repetition {}", _0, _1)]
|
||||
#[error("{}: match not found on repetition {}", ._0.quote(), _1)]
|
||||
MatchNotFoundOnRepetition(String, usize),
|
||||
#[error("line number must be greater than zero")]
|
||||
LineNumberIsZero,
|
||||
#[error("line number '{}' is smaller than preceding line number, {}", _0, _1)]
|
||||
LineNumberSmallerThanPrevious(usize, usize),
|
||||
#[error("invalid pattern: {}", _0)]
|
||||
#[error("{}: invalid pattern", ._0.quote())]
|
||||
InvalidPattern(String),
|
||||
#[error("invalid number: '{}'", _0)]
|
||||
#[error("invalid number: {}", ._0.quote())]
|
||||
InvalidNumber(String),
|
||||
#[error("incorrect conversion specification in suffix")]
|
||||
SuffixFormatIncorrect,
|
||||
|
|
|
@ -15,6 +15,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::fs::File;
|
||||
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
use self::searcher::Searcher;
|
||||
use uucore::ranges::Range;
|
||||
|
@ -351,19 +352,19 @@ fn cut_files(mut filenames: Vec<String>, mode: Mode) -> i32 {
|
|||
let path = Path::new(&filename[..]);
|
||||
|
||||
if path.is_dir() {
|
||||
show_error!("{}: Is a directory", filename);
|
||||
show_error!("{}: Is a directory", filename.maybe_quote());
|
||||
continue;
|
||||
}
|
||||
|
||||
if path.metadata().is_err() {
|
||||
show_error!("{}: No such file or directory", filename);
|
||||
show_error!("{}: No such file or directory", filename.maybe_quote());
|
||||
continue;
|
||||
}
|
||||
|
||||
let file = match File::open(&path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
show_error!("opening '{}': {}", &filename[..], e);
|
||||
show_error!("opening {}: {}", filename.quote(), e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ use libc::{clock_settime, timespec, CLOCK_REALTIME};
|
|||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
use uucore::display::Quotable;
|
||||
#[cfg(windows)]
|
||||
use winapi::{
|
||||
shared::minwindef::WORD,
|
||||
|
@ -145,7 +146,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
|
||||
if !form.starts_with('+') {
|
||||
eprintln!("date: invalid date '{}'", form);
|
||||
eprintln!("date: invalid date {}", form.quote());
|
||||
return 1;
|
||||
}
|
||||
let form = form[1..].to_string();
|
||||
|
@ -174,7 +175,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let set_to = match matches.value_of(OPT_SET).map(parse_date) {
|
||||
None => None,
|
||||
Some(Err((input, _err))) => {
|
||||
eprintln!("date: invalid date '{}'", input);
|
||||
eprintln!("date: invalid date {}", input.quote());
|
||||
return 1;
|
||||
}
|
||||
Some(Ok(date)) => Some(date),
|
||||
|
@ -240,7 +241,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
println!("{}", formatted);
|
||||
}
|
||||
Err((input, _err)) => {
|
||||
println!("date: invalid date '{}'", input);
|
||||
println!("date: invalid date {}", input.quote());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::fs::File;
|
|||
use std::io::{BufRead, BufReader};
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use uucore::display::Quotable;
|
||||
|
||||
mod options {
|
||||
pub const BOURNE_SHELL: &str = "bourne-shell";
|
||||
|
@ -94,9 +95,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if matches.is_present(options::PRINT_DATABASE) {
|
||||
if !files.is_empty() {
|
||||
show_usage_error!(
|
||||
"extra operand '{}'\nfile operands cannot be combined with \
|
||||
"extra operand {}\nfile operands cannot be combined with \
|
||||
--print-database (-p)",
|
||||
files[0]
|
||||
files[0].quote()
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
@ -126,7 +127,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
result = parse(INTERNAL_DB.lines(), out_format, "")
|
||||
} else {
|
||||
if files.len() > 1 {
|
||||
show_usage_error!("extra operand '{}'", files[1]);
|
||||
show_usage_error!("extra operand {}", files[1].quote());
|
||||
return 1;
|
||||
}
|
||||
match File::open(files[0]) {
|
||||
|
@ -135,7 +136,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
result = parse(fin.lines().filter_map(Result::ok), out_format, files[0])
|
||||
}
|
||||
Err(e) => {
|
||||
show_error!("{}: {}", files[0], e);
|
||||
show_error!("{}: {}", files[0].maybe_quote(), e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +315,8 @@ where
|
|||
if val.is_empty() {
|
||||
return Err(format!(
|
||||
"{}:{}: invalid line; missing second token",
|
||||
fp, num
|
||||
fp.maybe_quote(),
|
||||
num
|
||||
));
|
||||
}
|
||||
let lower = key.to_lowercase();
|
||||
|
@ -341,7 +343,12 @@ where
|
|||
} else if let Some(s) = table.get(lower.as_str()) {
|
||||
result.push_str(format!("{}={}:", s, val).as_str());
|
||||
} else {
|
||||
return Err(format!("{}:{}: unrecognized keyword {}", fp, num, key));
|
||||
return Err(format!(
|
||||
"{}:{}: unrecognized keyword {}",
|
||||
fp.maybe_quote(),
|
||||
num,
|
||||
key
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ extern crate uucore;
|
|||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use std::path::Path;
|
||||
use uucore::display::print_verbatim;
|
||||
use uucore::error::{UResult, UUsageError};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
|
@ -65,7 +66,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
if d.components().next() == None {
|
||||
print!(".")
|
||||
} else {
|
||||
print!("{}", d.to_string_lossy());
|
||||
print_verbatim(d).unwrap();
|
||||
}
|
||||
}
|
||||
None => {
|
||||
|
|
|
@ -32,6 +32,7 @@ use std::path::PathBuf;
|
|||
use std::str::FromStr;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
use std::{error::Error, fmt::Display};
|
||||
use uucore::display::{print_verbatim, Quotable};
|
||||
use uucore::error::{UError, UResult};
|
||||
use uucore::parse_size::{parse_size, ParseSizeError};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
@ -293,9 +294,9 @@ fn du(
|
|||
Err(e) => {
|
||||
safe_writeln!(
|
||||
stderr(),
|
||||
"{}: cannot read directory '{}': {}",
|
||||
"{}: cannot read directory {}: {}",
|
||||
options.util_name,
|
||||
my_stat.path.display(),
|
||||
my_stat.path.quote(),
|
||||
e
|
||||
);
|
||||
return Box::new(iter::once(my_stat));
|
||||
|
@ -334,11 +335,11 @@ fn du(
|
|||
}
|
||||
Err(error) => match error.kind() {
|
||||
ErrorKind::PermissionDenied => {
|
||||
let description = format!("cannot access '{}'", entry.path().display());
|
||||
let description = format!("cannot access {}", entry.path().quote());
|
||||
let error_message = "Permission denied";
|
||||
show_error_custom_description!(description, "{}", error_message)
|
||||
}
|
||||
_ => show_error!("cannot access '{}': {}", entry.path().display(), error),
|
||||
_ => show_error!("cannot access {}: {}", entry.path().quote(), error),
|
||||
},
|
||||
},
|
||||
Err(error) => show_error!("{}", error),
|
||||
|
@ -411,26 +412,30 @@ enum DuError {
|
|||
impl Display for DuError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
DuError::InvalidMaxDepthArg(s) => write!(f, "invalid maximum depth '{}'", s),
|
||||
DuError::InvalidMaxDepthArg(s) => write!(f, "invalid maximum depth {}", s.quote()),
|
||||
DuError::SummarizeDepthConflict(s) => {
|
||||
write!(f, "summarizing conflicts with --max-depth={}", s)
|
||||
write!(
|
||||
f,
|
||||
"summarizing conflicts with --max-depth={}",
|
||||
s.maybe_quote()
|
||||
)
|
||||
}
|
||||
DuError::InvalidTimeStyleArg(s) => write!(
|
||||
f,
|
||||
"invalid argument '{}' for 'time style'
|
||||
"invalid argument {} for 'time style'
|
||||
Valid arguments are:
|
||||
- 'full-iso'
|
||||
- 'long-iso'
|
||||
- 'iso'
|
||||
Try '{} --help' for more information.",
|
||||
s,
|
||||
s.quote(),
|
||||
uucore::execution_phrase()
|
||||
),
|
||||
DuError::InvalidTimeArg(s) => write!(
|
||||
f,
|
||||
"Invalid argument '{}' for --time.
|
||||
"Invalid argument {} for --time.
|
||||
'birth' and 'creation' arguments are not supported on this platform.",
|
||||
s
|
||||
s.quote()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -566,21 +571,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
};
|
||||
if !summarize || index == len - 1 {
|
||||
let time_str = tm.format(time_format_str).to_string();
|
||||
print!(
|
||||
"{}\t{}\t{}{}",
|
||||
convert_size(size),
|
||||
time_str,
|
||||
stat.path.display(),
|
||||
line_separator
|
||||
);
|
||||
print!("{}\t{}\t", convert_size(size), time_str);
|
||||
print_verbatim(stat.path).unwrap();
|
||||
print!("{}", line_separator);
|
||||
}
|
||||
} else if !summarize || index == len - 1 {
|
||||
print!(
|
||||
"{}\t{}{}",
|
||||
convert_size(size),
|
||||
stat.path.display(),
|
||||
line_separator
|
||||
);
|
||||
print!("{}\t", convert_size(size));
|
||||
print_verbatim(stat.path).unwrap();
|
||||
print!("{}", line_separator);
|
||||
}
|
||||
if options.total && index == (len - 1) {
|
||||
// The last element will be the total size of the the path under
|
||||
|
@ -590,7 +588,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
}
|
||||
}
|
||||
Err(_) => {
|
||||
show_error!("{}: {}", path_string, "No such file or directory");
|
||||
show_error!(
|
||||
"{}: {}",
|
||||
path_string.maybe_quote(),
|
||||
"No such file or directory"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -837,8 +839,8 @@ fn format_error_message(error: ParseSizeError, s: &str, option: &str) -> String
|
|||
// GNU's du echos affected flag, -B or --block-size (-t or --threshold), depending user's selection
|
||||
// GNU's du does distinguish between "invalid (suffix in) argument"
|
||||
match error {
|
||||
ParseSizeError::ParseFailure(_) => format!("invalid --{} argument '{}'", option, s),
|
||||
ParseSizeError::SizeTooBig(_) => format!("--{} argument '{}' too large", option, s),
|
||||
ParseSizeError::ParseFailure(_) => format!("invalid --{} argument {}", option, s.quote()),
|
||||
ParseSizeError::SizeTooBig(_) => format!("--{} argument {} too large", option, s.quote()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
src/uu/env/src/env.rs
vendored
10
src/uu/env/src/env.rs
vendored
|
@ -65,8 +65,14 @@ fn parse_name_value_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<bool
|
|||
|
||||
fn parse_program_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<(), i32> {
|
||||
if opts.null {
|
||||
eprintln!("{}: cannot specify --null (-0) with command", crate_name!());
|
||||
eprintln!("Type \"{} --help\" for detailed information", crate_name!());
|
||||
eprintln!(
|
||||
"{}: cannot specify --null (-0) with command",
|
||||
uucore::util_name()
|
||||
);
|
||||
eprintln!(
|
||||
"Type \"{} --help\" for detailed information",
|
||||
uucore::execution_phrase()
|
||||
);
|
||||
Err(1)
|
||||
} else {
|
||||
opts.program.push(opt);
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::fs::File;
|
|||
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
|
||||
use std::str::from_utf8;
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
static ABOUT: &str = "Convert tabs in each FILE to spaces, writing to standard output.
|
||||
With no FILE, or when FILE is -, read standard input.";
|
||||
|
@ -216,7 +217,7 @@ fn open(path: String) -> BufReader<Box<dyn Read + 'static>> {
|
|||
} else {
|
||||
file_buf = match File::open(&path[..]) {
|
||||
Ok(a) => a,
|
||||
Err(e) => crash!(1, "{}: {}\n", &path[..], e),
|
||||
Err(e) => crash!(1, "{}: {}\n", path.maybe_quote(), e),
|
||||
};
|
||||
BufReader::new(Box::new(file_buf) as Box<dyn Read>)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use std::io::{self, stdin, stdout, BufRead, Write};
|
|||
mod factor;
|
||||
use clap::{crate_version, App, Arg};
|
||||
pub use factor::*;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
mod miller_rabin;
|
||||
pub mod numeric;
|
||||
|
@ -52,7 +53,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if let Some(values) = matches.values_of(options::NUMBER) {
|
||||
for number in values {
|
||||
if let Err(e) = print_factors_str(number, &mut w, &mut factors_buffer) {
|
||||
show_warning!("{}: {}", number, e);
|
||||
show_warning!("{}: {}", number.maybe_quote(), e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -61,7 +62,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
for line in stdin.lock().lines() {
|
||||
for number in line.unwrap().split_whitespace() {
|
||||
if let Err(e) = print_factors_str(number, &mut w, &mut factors_buffer) {
|
||||
show_warning!("{}: {}", number, e);
|
||||
show_warning!("{}: {}", number.maybe_quote(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use std::cmp;
|
|||
use std::fs::File;
|
||||
use std::io::{stdin, stdout, Write};
|
||||
use std::io::{BufReader, BufWriter, Read};
|
||||
use uucore::display::Quotable;
|
||||
|
||||
use self::linebreak::break_lines;
|
||||
use self::parasplit::ParagraphStream;
|
||||
|
@ -187,7 +188,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
_ => match File::open(i) {
|
||||
Ok(f) => BufReader::new(Box::new(f) as Box<dyn Read + 'static>),
|
||||
Err(e) => {
|
||||
show_warning!("{}: {}", i, e);
|
||||
show_warning!("{}: {}", i.maybe_quote(), e);
|
||||
continue;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
use uucore::entries::{get_groups_gnu, gid2grp, Locate, Passwd};
|
||||
use uucore::{
|
||||
display::Quotable,
|
||||
entries::{get_groups_gnu, gid2grp, Locate, Passwd},
|
||||
};
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
|
||||
|
@ -77,7 +80,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.join(" ")
|
||||
);
|
||||
} else {
|
||||
show_error!("'{}': no such user", user);
|
||||
show_error!("{}: no such user", user.quote());
|
||||
exit_code = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ use std::io::{self, stdin, BufRead, BufReader, Read};
|
|||
use std::iter;
|
||||
use std::num::ParseIntError;
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
const NAME: &str = "hashsum";
|
||||
|
||||
|
@ -525,7 +526,7 @@ where
|
|||
if options.warn {
|
||||
show_warning!(
|
||||
"{}: {}: improperly formatted {} checksum line",
|
||||
filename.display(),
|
||||
filename.maybe_quote(),
|
||||
i + 1,
|
||||
options.algoname
|
||||
);
|
||||
|
@ -546,6 +547,10 @@ where
|
|||
)
|
||||
)
|
||||
.to_ascii_lowercase();
|
||||
// FIXME: (How) should these be quoted?
|
||||
// They seem like they would be processed programmatically, and
|
||||
// our ordinary quoting might interfere, but newlines should be
|
||||
// sanitized probably
|
||||
if sum == real_sum {
|
||||
if !options.quiet {
|
||||
println!("{}: OK", ck_filename);
|
||||
|
|
|
@ -9,6 +9,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::convert::TryFrom;
|
||||
use std::ffi::OsString;
|
||||
use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::{crash, show_error_custom_description};
|
||||
|
||||
const EXIT_FAILURE: i32 = 1;
|
||||
|
@ -127,10 +128,10 @@ fn arg_iterate<'a>(
|
|||
match parse::parse_obsolete(s) {
|
||||
Some(Ok(iter)) => Ok(Box::new(vec![first].into_iter().chain(iter).chain(args))),
|
||||
Some(Err(e)) => match e {
|
||||
parse::ParseError::Syntax => Err(format!("bad argument format: '{}'", s)),
|
||||
parse::ParseError::Syntax => Err(format!("bad argument format: {}", s.quote())),
|
||||
parse::ParseError::Overflow => Err(format!(
|
||||
"invalid argument: '{}' Value too large for defined datatype",
|
||||
s
|
||||
"invalid argument: {} Value too large for defined datatype",
|
||||
s.quote()
|
||||
)),
|
||||
},
|
||||
None => Ok(Box::new(vec![first, second].into_iter().chain(args))),
|
||||
|
@ -418,7 +419,7 @@ fn uu_head(options: &HeadOptions) -> Result<(), u32> {
|
|||
let mut file = match std::fs::File::open(name) {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
let prefix = format!("cannot open '{}' for reading", name);
|
||||
let prefix = format!("cannot open {} for reading", name.quote());
|
||||
match err.kind() {
|
||||
ErrorKind::NotFound => {
|
||||
show_error_custom_description!(prefix, "No such file or directory");
|
||||
|
|
|
@ -41,6 +41,7 @@ extern crate uucore;
|
|||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use std::ffi::CStr;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::entries::{self, Group, Locate, Passwd};
|
||||
use uucore::error::UResult;
|
||||
use uucore::error::{set_exit_code, USimpleError};
|
||||
|
@ -230,7 +231,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
match Passwd::locate(users[i].as_str()) {
|
||||
Ok(p) => Some(p),
|
||||
Err(_) => {
|
||||
show_error!("'{}': no such user", users[i]);
|
||||
show_error!("{}: no such user", users[i].quote());
|
||||
set_exit_code(1);
|
||||
if i + 1 >= users.len() {
|
||||
break;
|
||||
|
|
|
@ -16,6 +16,7 @@ use clap::{crate_version, App, Arg, ArgMatches};
|
|||
use file_diff::diff;
|
||||
use filetime::{set_file_times, FileTime};
|
||||
use uucore::backup_control::{self, BackupMode};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::entries::{grp2gid, usr2uid};
|
||||
use uucore::error::{FromIo, UError, UIoError, UResult};
|
||||
use uucore::mode::get_umask;
|
||||
|
@ -95,40 +96,30 @@ impl Display for InstallError {
|
|||
)
|
||||
}
|
||||
IE::CreateDirFailed(dir, e) => {
|
||||
Display::fmt(&uio_error!(e, "failed to create {}", dir.display()), f)
|
||||
Display::fmt(&uio_error!(e, "failed to create {}", dir.quote()), f)
|
||||
}
|
||||
IE::ChmodFailed(file) => write!(f, "failed to chmod {}", file.display()),
|
||||
IE::ChmodFailed(file) => write!(f, "failed to chmod {}", file.quote()),
|
||||
IE::InvalidTarget(target) => write!(
|
||||
f,
|
||||
"invalid target {}: No such file or directory",
|
||||
target.display()
|
||||
target.quote()
|
||||
),
|
||||
IE::TargetDirIsntDir(target) => {
|
||||
write!(f, "target '{}' is not a directory", target.display())
|
||||
write!(f, "target {} is not a directory", target.quote())
|
||||
}
|
||||
IE::BackupFailed(from, to, e) => Display::fmt(
|
||||
&uio_error!(
|
||||
e,
|
||||
"cannot backup '{}' to '{}'",
|
||||
from.display(),
|
||||
to.display()
|
||||
),
|
||||
&uio_error!(e, "cannot backup {} to {}", from.quote(), to.quote()),
|
||||
f,
|
||||
),
|
||||
IE::InstallFailed(from, to, e) => Display::fmt(
|
||||
&uio_error!(
|
||||
e,
|
||||
"cannot install '{}' to '{}'",
|
||||
from.display(),
|
||||
to.display()
|
||||
),
|
||||
&uio_error!(e, "cannot install {} to {}", from.quote(), to.quote()),
|
||||
f,
|
||||
),
|
||||
IE::StripProgramFailed(msg) => write!(f, "strip program failed: {}", msg),
|
||||
IE::MetadataFailed(e) => Display::fmt(&uio_error!(e, ""), f),
|
||||
IE::NoSuchUser(user) => write!(f, "no such user: {}", user),
|
||||
IE::NoSuchGroup(group) => write!(f, "no such group: {}", group),
|
||||
IE::OmittingDirectory(dir) => write!(f, "omitting directory '{}'", dir.display()),
|
||||
IE::NoSuchUser(user) => write!(f, "no such user: {}", user.maybe_quote()),
|
||||
IE::NoSuchGroup(group) => write!(f, "no such group: {}", group.maybe_quote()),
|
||||
IE::OmittingDirectory(dir) => write!(f, "omitting directory {}", dir.quote()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,14 +407,14 @@ fn directory(paths: Vec<String>, b: Behavior) -> UResult<()> {
|
|||
// the default mode. Hence it is safe to use fs::create_dir_all
|
||||
// and then only modify the target's dir mode.
|
||||
if let Err(e) =
|
||||
fs::create_dir_all(path).map_err_context(|| format!("{}", path.display()))
|
||||
fs::create_dir_all(path).map_err_context(|| path.maybe_quote().to_string())
|
||||
{
|
||||
show!(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if b.verbose {
|
||||
println!("creating directory '{}'", path.display());
|
||||
println!("creating directory {}", path.quote());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,7 +436,7 @@ fn directory(paths: Vec<String>, b: Behavior) -> UResult<()> {
|
|||
fn is_new_file_path(path: &Path) -> bool {
|
||||
!path.exists()
|
||||
&& (path.parent().map(Path::is_dir).unwrap_or(true)
|
||||
|| path.parent().unwrap().to_string_lossy().is_empty()) // In case of a simple file
|
||||
|| path.parent().unwrap().as_os_str().is_empty()) // In case of a simple file
|
||||
}
|
||||
|
||||
/// Perform an install, given a list of paths and behavior.
|
||||
|
@ -502,7 +493,7 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UR
|
|||
if !sourcepath.exists() {
|
||||
let err = UIoError::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
format!("cannot stat '{}'", sourcepath.display()),
|
||||
format!("cannot stat {}", sourcepath.quote()),
|
||||
);
|
||||
show!(err);
|
||||
continue;
|
||||
|
@ -566,7 +557,7 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> {
|
|||
}
|
||||
}
|
||||
|
||||
if from.to_string_lossy() == "/dev/null" {
|
||||
if from.as_os_str() == "/dev/null" {
|
||||
/* workaround a limitation of fs::copy
|
||||
* https://github.com/rust-lang/rust/issues/79390
|
||||
*/
|
||||
|
@ -674,9 +665,9 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> {
|
|||
}
|
||||
|
||||
if b.verbose {
|
||||
print!("'{}' -> '{}'", from.display(), to.display());
|
||||
print!("{} -> {}", from.quote(), to.quote());
|
||||
match backup_path {
|
||||
Some(path) => println!(" (backup: '{}')", path.display()),
|
||||
Some(path) => println!(" (backup: {})", path.quote()),
|
||||
None => println!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,9 @@ pub fn parse(mode_string: &str, considering_dir: bool, umask: u32) -> Result<u32
|
|||
#[cfg(any(unix, target_os = "redox"))]
|
||||
pub fn chmod(path: &Path, mode: u32) -> Result<(), ()> {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use uucore::display::Quotable;
|
||||
fs::set_permissions(path, fs::Permissions::from_mode(mode)).map_err(|err| {
|
||||
show_error!("{}: chmod failed with error {}", path.display(), err);
|
||||
show_error!("{}: chmod failed with error {}", path.maybe_quote(), err);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::cmp::Ordering;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Lines, Stdin};
|
||||
use uucore::display::Quotable;
|
||||
|
||||
static NAME: &str = "join";
|
||||
|
||||
|
@ -181,18 +182,18 @@ impl Spec {
|
|||
return Spec::Key;
|
||||
}
|
||||
|
||||
crash!(1, "invalid field specifier: '{}'", format);
|
||||
crash!(1, "invalid field specifier: {}", format.quote());
|
||||
}
|
||||
Some('1') => FileNum::File1,
|
||||
Some('2') => FileNum::File2,
|
||||
_ => crash!(1, "invalid file number in field spec: '{}'", format),
|
||||
_ => crash!(1, "invalid file number in field spec: {}", format.quote()),
|
||||
};
|
||||
|
||||
if let Some('.') = chars.next() {
|
||||
return Spec::Field(file_num, parse_field_number(chars.as_str()));
|
||||
}
|
||||
|
||||
crash!(1, "invalid field specifier: '{}'", format);
|
||||
crash!(1, "invalid field specifier: {}", format.quote());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,7 +246,7 @@ impl<'a> State<'a> {
|
|||
} else {
|
||||
match File::open(name) {
|
||||
Ok(file) => Box::new(BufReader::new(file)) as Box<dyn BufRead>,
|
||||
Err(err) => crash!(1, "{}: {}", name, err),
|
||||
Err(err) => crash!(1, "{}: {}", name.maybe_quote(), err),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -393,7 +394,11 @@ impl<'a> State<'a> {
|
|||
let diff = input.compare(self.get_current_key(), line.get_field(self.key));
|
||||
|
||||
if diff == Ordering::Greater {
|
||||
eprintln!("{}:{}: is not sorted", self.file_name, self.line_num);
|
||||
eprintln!(
|
||||
"{}:{}: is not sorted",
|
||||
self.file_name.maybe_quote(),
|
||||
self.line_num
|
||||
);
|
||||
|
||||
// This is fatal if the check is enabled.
|
||||
if input.check_order == CheckOrder::Enabled {
|
||||
|
@ -727,7 +732,7 @@ fn get_field_number(keys: Option<usize>, key: Option<usize>) -> usize {
|
|||
fn parse_field_number(value: &str) -> usize {
|
||||
match value.parse::<usize>() {
|
||||
Ok(result) if result > 0 => result - 1,
|
||||
_ => crash!(1, "invalid field number: '{}'", value),
|
||||
_ => crash!(1, "invalid field number: {}", value.quote()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -735,7 +740,7 @@ fn parse_file_number(value: &str) -> FileNum {
|
|||
match value {
|
||||
"1" => FileNum::File1,
|
||||
"2" => FileNum::File2,
|
||||
value => crash!(1, "invalid file number: '{}'", value),
|
||||
value => crash!(1, "invalid file number: {}", value.quote()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ extern crate uucore;
|
|||
use clap::{crate_version, App, Arg};
|
||||
use libc::{c_int, pid_t};
|
||||
use std::io::Error;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{UResult, USimpleError};
|
||||
use uucore::signals::ALL_SIGNALS;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
@ -154,7 +155,7 @@ fn print_signal(signal_name_or_value: &str) -> UResult<()> {
|
|||
}
|
||||
Err(USimpleError::new(
|
||||
1,
|
||||
format!("unknown signal name {}", signal_name_or_value),
|
||||
format!("unknown signal name {}", signal_name_or_value.quote()),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -190,7 +191,7 @@ fn kill(signalname: &str, pids: &[String]) -> UResult<()> {
|
|||
None => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("unknown signal name {}", signalname),
|
||||
format!("unknown signal name {}", signalname.quote()),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
@ -204,7 +205,7 @@ fn kill(signalname: &str, pids: &[String]) -> UResult<()> {
|
|||
Err(e) => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("failed to parse argument {}: {}", pid, e),
|
||||
format!("failed to parse argument {}: {}", pid.quote(), e),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{UError, UResult};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::error::Error;
|
||||
use std::ffi::OsStr;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt::Display;
|
||||
use std::fs;
|
||||
|
||||
|
@ -49,26 +50,26 @@ pub enum OverwriteMode {
|
|||
|
||||
#[derive(Debug)]
|
||||
enum LnError {
|
||||
TargetIsDirectory(String),
|
||||
TargetIsDirectory(PathBuf),
|
||||
SomeLinksFailed,
|
||||
FailedToLink(String),
|
||||
MissingDestination(String),
|
||||
ExtraOperand(String),
|
||||
MissingDestination(PathBuf),
|
||||
ExtraOperand(OsString),
|
||||
}
|
||||
|
||||
impl Display for LnError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::TargetIsDirectory(s) => write!(f, "target '{}' is not a directory", s),
|
||||
Self::FailedToLink(s) => write!(f, "failed to link '{}'", s),
|
||||
Self::TargetIsDirectory(s) => write!(f, "target {} is not a directory", s.quote()),
|
||||
Self::FailedToLink(e) => write!(f, "failed to link: {}", e),
|
||||
Self::SomeLinksFailed => write!(f, "some links failed to create"),
|
||||
Self::MissingDestination(s) => {
|
||||
write!(f, "missing destination file operand after '{}'", s)
|
||||
write!(f, "missing destination file operand after {}", s.quote())
|
||||
}
|
||||
Self::ExtraOperand(s) => write!(
|
||||
f,
|
||||
"extra operand '{}'\nTry '{} --help' for more information.",
|
||||
s,
|
||||
"extra operand {}\nTry '{} --help' for more information.",
|
||||
s.quote(),
|
||||
uucore::execution_phrase()
|
||||
),
|
||||
}
|
||||
|
@ -279,10 +280,10 @@ fn exec(files: &[PathBuf], settings: &Settings) -> UResult<()> {
|
|||
// 1st form. Now there should be only two operands, but if -T is
|
||||
// specified we may have a wrong number of operands.
|
||||
if files.len() == 1 {
|
||||
return Err(LnError::MissingDestination(files[0].to_string_lossy().into()).into());
|
||||
return Err(LnError::MissingDestination(files[0].clone()).into());
|
||||
}
|
||||
if files.len() > 2 {
|
||||
return Err(LnError::ExtraOperand(files[2].display().to_string()).into());
|
||||
return Err(LnError::ExtraOperand(files[2].clone().into()).into());
|
||||
}
|
||||
assert!(!files.is_empty());
|
||||
|
||||
|
@ -294,7 +295,7 @@ fn exec(files: &[PathBuf], settings: &Settings) -> UResult<()> {
|
|||
|
||||
fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings) -> UResult<()> {
|
||||
if !target_dir.is_dir() {
|
||||
return Err(LnError::TargetIsDirectory(target_dir.display().to_string()).into());
|
||||
return Err(LnError::TargetIsDirectory(target_dir.to_owned()).into());
|
||||
}
|
||||
|
||||
let mut all_successful = true;
|
||||
|
@ -306,7 +307,7 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
|
|||
if is_symlink(target_dir) {
|
||||
if target_dir.is_file() {
|
||||
if let Err(e) = fs::remove_file(target_dir) {
|
||||
show_error!("Could not update {}: {}", target_dir.display(), e)
|
||||
show_error!("Could not update {}: {}", target_dir.quote(), e)
|
||||
};
|
||||
}
|
||||
if target_dir.is_dir() {
|
||||
|
@ -314,7 +315,7 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
|
|||
// considered as a dir
|
||||
// See test_ln::test_symlink_no_deref_dir
|
||||
if let Err(e) = fs::remove_dir(target_dir) {
|
||||
show_error!("Could not update {}: {}", target_dir.display(), e)
|
||||
show_error!("Could not update {}: {}", target_dir.quote(), e)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -332,10 +333,7 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
|
|||
}
|
||||
}
|
||||
None => {
|
||||
show_error!(
|
||||
"cannot stat '{}': No such file or directory",
|
||||
srcpath.display()
|
||||
);
|
||||
show_error!("cannot stat {}: No such file or directory", srcpath.quote());
|
||||
all_successful = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -344,9 +342,9 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings)
|
|||
|
||||
if let Err(e) = link(srcpath, &targetpath, settings) {
|
||||
show_error!(
|
||||
"cannot link '{}' to '{}': {}",
|
||||
targetpath.display(),
|
||||
srcpath.display(),
|
||||
"cannot link {} to {}: {}",
|
||||
targetpath.quote(),
|
||||
srcpath.quote(),
|
||||
e
|
||||
);
|
||||
all_successful = false;
|
||||
|
@ -399,7 +397,7 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> Result<()> {
|
|||
match settings.overwrite {
|
||||
OverwriteMode::NoClobber => {}
|
||||
OverwriteMode::Interactive => {
|
||||
print!("{}: overwrite '{}'? ", uucore::util_name(), dst.display());
|
||||
print!("{}: overwrite {}? ", uucore::util_name(), dst.quote());
|
||||
if !read_yes() {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -426,9 +424,9 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> Result<()> {
|
|||
}
|
||||
|
||||
if settings.verbose {
|
||||
print!("'{}' -> '{}'", dst.display(), &source.display());
|
||||
print!("{} -> {}", dst.quote(), source.quote());
|
||||
match backup_path {
|
||||
Some(path) => println!(" (backup: '{}')", path.display()),
|
||||
Some(path) => println!(" (backup: {})", path.quote()),
|
||||
None => println!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,10 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
||||
use uucore::error::{set_exit_code, FromIo, UError, UResult};
|
||||
use uucore::{
|
||||
display::Quotable,
|
||||
error::{set_exit_code, FromIo, UError, UResult},
|
||||
};
|
||||
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
#[cfg(unix)]
|
||||
|
@ -150,8 +153,8 @@ impl Error for LsError {}
|
|||
impl Display for LsError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
LsError::InvalidLineWidth(s) => write!(f, "invalid line width: '{}'", s),
|
||||
LsError::NoMetadata(p) => write!(f, "could not open file: '{}'", p.display()),
|
||||
LsError::InvalidLineWidth(s) => write!(f, "invalid line width: {}", s.quote()),
|
||||
LsError::NoMetadata(p) => write!(f, "could not open file: {}", p.quote()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,18 +413,18 @@ impl Config {
|
|||
},
|
||||
None => match termsize::get() {
|
||||
Some(size) => size.cols,
|
||||
None => match std::env::var("COLUMNS") {
|
||||
Ok(columns) => match columns.parse() {
|
||||
Ok(columns) => columns,
|
||||
Err(_) => {
|
||||
None => match std::env::var_os("COLUMNS") {
|
||||
Some(columns) => match columns.to_str().and_then(|s| s.parse().ok()) {
|
||||
Some(columns) => columns,
|
||||
None => {
|
||||
show_error!(
|
||||
"ignoring invalid width in environment variable COLUMNS: '{}'",
|
||||
columns
|
||||
"ignoring invalid width in environment variable COLUMNS: {}",
|
||||
columns.quote()
|
||||
);
|
||||
DEFAULT_TERM_WIDTH
|
||||
}
|
||||
},
|
||||
Err(_) => DEFAULT_TERM_WIDTH,
|
||||
None => DEFAULT_TERM_WIDTH,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -538,7 +541,7 @@ impl Config {
|
|||
Ok(p) => {
|
||||
ignore_patterns.add(p);
|
||||
}
|
||||
Err(_) => show_warning!("Invalid pattern for ignore: '{}'", pattern),
|
||||
Err(_) => show_warning!("Invalid pattern for ignore: {}", pattern.quote()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +551,7 @@ impl Config {
|
|||
Ok(p) => {
|
||||
ignore_patterns.add(p);
|
||||
}
|
||||
Err(_) => show_warning!("Invalid pattern for hide: '{}'", pattern),
|
||||
Err(_) => show_warning!("Invalid pattern for hide: {}", pattern.quote()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1255,7 +1258,7 @@ fn list(locs: Vec<&Path>, config: Config) -> UResult<()> {
|
|||
|
||||
if path_data.md().is_none() {
|
||||
show!(std::io::ErrorKind::NotFound
|
||||
.map_err_context(|| format!("cannot access '{}'", path_data.p_buf.display())));
|
||||
.map_err_context(|| format!("cannot access {}", path_data.p_buf.quote())));
|
||||
// We found an error, no need to continue the execution
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use clap::OsValues;
|
|||
use clap::{crate_version, App, Arg};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UResult, USimpleError};
|
||||
|
||||
static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist";
|
||||
|
@ -43,7 +44,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
// Not tested on Windows
|
||||
let mode: u16 = match matches.value_of(options::MODE) {
|
||||
Some(m) => u16::from_str_radix(m, 8)
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid mode '{}'", m)))?,
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid mode {}", m.quote())))?,
|
||||
None => 0o755_u16,
|
||||
};
|
||||
|
||||
|
@ -100,13 +101,13 @@ fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> UResult<()>
|
|||
fs::create_dir
|
||||
};
|
||||
|
||||
create_dir(path).map_err_context(|| format!("cannot create directory '{}'", path.display()))?;
|
||||
create_dir(path).map_err_context(|| format!("cannot create directory {}", path.quote()))?;
|
||||
|
||||
if verbose {
|
||||
println!(
|
||||
"{}: created directory '{}'",
|
||||
"{}: created directory {}",
|
||||
uucore::util_name(),
|
||||
path.display()
|
||||
path.quote()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -121,7 +122,7 @@ fn chmod(path: &Path, mode: u16) -> UResult<()> {
|
|||
let mode = Permissions::from_mode(u32::from(mode));
|
||||
|
||||
set_permissions(path, mode)
|
||||
.map_err_context(|| format!("cannot set permissions '{}'", path.display()))
|
||||
.map_err_context(|| format!("cannot set permissions {}", path.quote()))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
|
@ -11,7 +11,7 @@ extern crate uucore;
|
|||
use clap::{crate_version, App, Arg};
|
||||
use libc::mkfifo;
|
||||
use std::ffi::CString;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
use uucore::{display::Quotable, InvalidEncodingHandling};
|
||||
|
||||
static NAME: &str = "mkfifo";
|
||||
static USAGE: &str = "mkfifo [OPTION]... NAME...";
|
||||
|
@ -61,7 +61,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
mkfifo(name.as_ptr(), mode as libc::mode_t)
|
||||
};
|
||||
if err == -1 {
|
||||
show_error!("cannot create fifo '{}': File exists", f);
|
||||
show_error!("cannot create fifo {}: File exists", f.quote());
|
||||
exit_code = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use clap::{crate_version, App, Arg, ArgMatches};
|
|||
use libc::{dev_t, mode_t};
|
||||
use libc::{S_IFBLK, S_IFCHR, S_IFIFO, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR};
|
||||
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static ABOUT: &str = "Create the special file NAME of the given TYPE.";
|
||||
|
@ -219,7 +220,7 @@ fn valid_type(tpe: String) -> Result<(), String> {
|
|||
if vec!['b', 'c', 'u', 'p'].contains(&first_char) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("invalid device type '{}'", tpe))
|
||||
Err(format!("invalid device type {}", tpe.quote()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use uucore::display::{println_verbatim, Quotable};
|
||||
use uucore::error::{FromIo, UError, UResult};
|
||||
|
||||
use std::env;
|
||||
|
@ -57,16 +58,20 @@ impl Display for MkTempError {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use MkTempError::*;
|
||||
match self {
|
||||
PersistError(p) => write!(f, "could not persist file '{}'", p.display()),
|
||||
MustEndInX(s) => write!(f, "with --suffix, template '{}' must end in X", s),
|
||||
TooFewXs(s) => write!(f, "too few X's in template '{}'", s),
|
||||
PersistError(p) => write!(f, "could not persist file {}", p.quote()),
|
||||
MustEndInX(s) => write!(f, "with --suffix, template {} must end in X", s.quote()),
|
||||
TooFewXs(s) => write!(f, "too few X's in template {}", s.quote()),
|
||||
ContainsDirSeparator(s) => {
|
||||
write!(f, "invalid suffix '{}', contains directory separator", s)
|
||||
write!(
|
||||
f,
|
||||
"invalid suffix {}, contains directory separator",
|
||||
s.quote()
|
||||
)
|
||||
}
|
||||
InvalidTemplate(s) => write!(
|
||||
f,
|
||||
"invalid template, '{}'; with --tmpdir, it may not be absolute",
|
||||
s
|
||||
"invalid template, {}; with --tmpdir, it may not be absolute",
|
||||
s.quote()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +249,7 @@ pub fn dry_exec(mut tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str) ->
|
|||
}
|
||||
}
|
||||
tmpdir.push(buf);
|
||||
println!("{}", tmpdir.display());
|
||||
Ok(())
|
||||
println_verbatim(tmpdir).map_err_context(|| "failed to print directory name".to_owned())
|
||||
}
|
||||
|
||||
fn exec(dir: PathBuf, prefix: &str, rand: usize, suffix: &str, make_dir: bool) -> UResult<()> {
|
||||
|
@ -274,6 +278,5 @@ fn exec(dir: PathBuf, prefix: &str, rand: usize, suffix: &str, make_dir: bool) -
|
|||
.map_err(|e| MkTempError::PersistError(e.file.path().to_path_buf()))?
|
||||
.1
|
||||
};
|
||||
println!("{}", path.display());
|
||||
Ok(())
|
||||
println_verbatim(path).map_err_context(|| "failed to print directory name".to_owned())
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ use crossterm::{
|
|||
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
const BELL: &str = "\x07";
|
||||
|
||||
|
@ -64,12 +65,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let file = Path::new(file);
|
||||
if file.is_dir() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_usage_error!("'{}' is a directory.", file.display());
|
||||
show_usage_error!("{} is a directory.", file.quote());
|
||||
return 1;
|
||||
}
|
||||
if !file.exists() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_error!("cannot open {}: No such file or directory", file.display());
|
||||
show_error!("cannot open {}: No such file or directory", file.quote());
|
||||
return 1;
|
||||
}
|
||||
if length > 1 {
|
||||
|
|
|
@ -21,6 +21,7 @@ use std::os::unix;
|
|||
use std::os::windows;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::backup_control::{self, BackupMode};
|
||||
use uucore::display::Quotable;
|
||||
|
||||
use fs_extra::dir::{move_dir, CopyOptions as DirCopyOptions};
|
||||
|
||||
|
@ -223,10 +224,7 @@ fn exec(files: &[PathBuf], b: Behavior) -> i32 {
|
|||
// `Ok()` results unless the source does not exist, or the user
|
||||
// lacks permission to access metadata.
|
||||
if source.symlink_metadata().is_err() {
|
||||
show_error!(
|
||||
"cannot stat '{}': No such file or directory",
|
||||
source.display()
|
||||
);
|
||||
show_error!("cannot stat {}: No such file or directory", source.quote());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -234,8 +232,8 @@ fn exec(files: &[PathBuf], b: Behavior) -> i32 {
|
|||
if b.no_target_dir {
|
||||
if !source.is_dir() {
|
||||
show_error!(
|
||||
"cannot overwrite directory '{}' with non-directory",
|
||||
target.display()
|
||||
"cannot overwrite directory {} with non-directory",
|
||||
target.quote()
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
@ -243,9 +241,9 @@ fn exec(files: &[PathBuf], b: Behavior) -> i32 {
|
|||
return match rename(source, target, &b) {
|
||||
Err(e) => {
|
||||
show_error!(
|
||||
"cannot move '{}' to '{}': {}",
|
||||
source.display(),
|
||||
target.display(),
|
||||
"cannot move {} to {}: {}",
|
||||
source.quote(),
|
||||
target.quote(),
|
||||
e.to_string()
|
||||
);
|
||||
1
|
||||
|
@ -257,9 +255,9 @@ fn exec(files: &[PathBuf], b: Behavior) -> i32 {
|
|||
return move_files_into_dir(&[source.clone()], target, &b);
|
||||
} else if target.exists() && source.is_dir() {
|
||||
show_error!(
|
||||
"cannot overwrite non-directory '{}' with directory '{}'",
|
||||
target.display(),
|
||||
source.display()
|
||||
"cannot overwrite non-directory {} with directory {}",
|
||||
target.quote(),
|
||||
source.quote()
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
@ -272,9 +270,9 @@ fn exec(files: &[PathBuf], b: Behavior) -> i32 {
|
|||
_ => {
|
||||
if b.no_target_dir {
|
||||
show_error!(
|
||||
"mv: extra operand '{}'\n\
|
||||
"mv: extra operand {}\n\
|
||||
Try '{} --help' for more information.",
|
||||
files[2].display(),
|
||||
files[2].quote(),
|
||||
uucore::execution_phrase()
|
||||
);
|
||||
return 1;
|
||||
|
@ -288,7 +286,7 @@ fn exec(files: &[PathBuf], b: Behavior) -> i32 {
|
|||
|
||||
fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> i32 {
|
||||
if !target_dir.is_dir() {
|
||||
show_error!("target '{}' is not a directory", target_dir.display());
|
||||
show_error!("target {} is not a directory", target_dir.quote());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -298,8 +296,8 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> i3
|
|||
Some(name) => target_dir.join(name),
|
||||
None => {
|
||||
show_error!(
|
||||
"cannot stat '{}': No such file or directory",
|
||||
sourcepath.display()
|
||||
"cannot stat {}: No such file or directory",
|
||||
sourcepath.quote()
|
||||
);
|
||||
|
||||
all_successful = false;
|
||||
|
@ -309,9 +307,9 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> i3
|
|||
|
||||
if let Err(e) = rename(sourcepath, &targetpath, b) {
|
||||
show_error!(
|
||||
"cannot move '{}' to '{}': {}",
|
||||
sourcepath.display(),
|
||||
targetpath.display(),
|
||||
"cannot move {} to {}: {}",
|
||||
sourcepath.quote(),
|
||||
targetpath.quote(),
|
||||
e.to_string()
|
||||
);
|
||||
all_successful = false;
|
||||
|
@ -332,7 +330,7 @@ fn rename(from: &Path, to: &Path, b: &Behavior) -> io::Result<()> {
|
|||
match b.overwrite {
|
||||
OverwriteMode::NoClobber => return Ok(()),
|
||||
OverwriteMode::Interactive => {
|
||||
println!("{}: overwrite '{}'? ", uucore::util_name(), to.display());
|
||||
println!("{}: overwrite {}? ", uucore::util_name(), to.quote());
|
||||
if !read_yes() {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -365,9 +363,9 @@ fn rename(from: &Path, to: &Path, b: &Behavior) -> io::Result<()> {
|
|||
rename_with_fallback(from, to)?;
|
||||
|
||||
if b.verbose {
|
||||
print!("'{}' -> '{}'", from.display(), to.display());
|
||||
print!("{} -> {}", from.quote(), to.quote());
|
||||
match backup_path {
|
||||
Some(path) => println!(" (backup: '{}')", path.display()),
|
||||
Some(path) => println!(" (backup: {})", path.quote()),
|
||||
None => println!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ use std::fs::{File, OpenOptions};
|
|||
use std::io::Error;
|
||||
use std::os::unix::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static ABOUT: &str = "Run COMMAND ignoring hangup signals.";
|
||||
|
@ -122,13 +123,16 @@ fn find_stdout() -> File {
|
|||
.open(Path::new(NOHUP_OUT))
|
||||
{
|
||||
Ok(t) => {
|
||||
show_error!("ignoring input and appending output to '{}'", NOHUP_OUT);
|
||||
show_error!(
|
||||
"ignoring input and appending output to {}",
|
||||
NOHUP_OUT.quote()
|
||||
);
|
||||
t
|
||||
}
|
||||
Err(e1) => {
|
||||
let home = match env::var("HOME") {
|
||||
Err(_) => {
|
||||
show_error!("failed to open '{}': {}", NOHUP_OUT, e1);
|
||||
show_error!("failed to open {}: {}", NOHUP_OUT.quote(), e1);
|
||||
exit!(internal_failure_code)
|
||||
}
|
||||
Ok(h) => h,
|
||||
|
@ -143,12 +147,15 @@ fn find_stdout() -> File {
|
|||
.open(&homeout)
|
||||
{
|
||||
Ok(t) => {
|
||||
show_error!("ignoring input and appending output to '{}'", homeout_str);
|
||||
show_error!(
|
||||
"ignoring input and appending output to {}",
|
||||
homeout_str.quote()
|
||||
);
|
||||
t
|
||||
}
|
||||
Err(e2) => {
|
||||
show_error!("failed to open '{}': {}", NOHUP_OUT, e1);
|
||||
show_error!("failed to open '{}': {}", homeout_str, e2);
|
||||
show_error!("failed to open {}: {}", NOHUP_OUT.quote(), e1);
|
||||
show_error!("failed to open {}: {}", homeout_str.quote(), e2);
|
||||
exit!(internal_failure_code)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use uucore::display::Quotable;
|
||||
|
||||
use crate::options::{NumfmtOptions, RoundMethod};
|
||||
use crate::units::{DisplayableSuffix, RawSuffix, Result, Suffix, Unit, IEC_BASES, SI_BASES};
|
||||
|
||||
|
@ -78,7 +80,7 @@ fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
|
|||
Some('Z') => Some((RawSuffix::Z, with_i)),
|
||||
Some('Y') => Some((RawSuffix::Y, with_i)),
|
||||
Some('0'..='9') => None,
|
||||
_ => return Err(format!("invalid suffix in input: '{}'", s)),
|
||||
_ => return Err(format!("invalid suffix in input: {}", s.quote())),
|
||||
};
|
||||
|
||||
let suffix_len = match suffix {
|
||||
|
@ -89,7 +91,7 @@ fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
|
|||
|
||||
let number = s[..s.len() - suffix_len]
|
||||
.parse::<f64>()
|
||||
.map_err(|_| format!("invalid number: '{}'", s))?;
|
||||
.map_err(|_| format!("invalid number: {}", s.quote()))?;
|
||||
|
||||
Ok((number, suffix))
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::options::*;
|
|||
use crate::units::{Result, Unit};
|
||||
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
|
||||
use std::io::{BufRead, Write};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::ranges::Range;
|
||||
|
||||
pub mod format;
|
||||
|
@ -113,7 +114,7 @@ fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
|
|||
0 => Err(value),
|
||||
_ => Ok(n),
|
||||
})
|
||||
.map_err(|value| format!("invalid header value '{}'", value))
|
||||
.map_err(|value| format!("invalid header value {}", value.quote()))
|
||||
}
|
||||
}?;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ use std::io;
|
|||
use std::io::BufReader;
|
||||
use std::vec::Vec;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
pub enum InputSource<'a> {
|
||||
FileName(&'a str),
|
||||
Stdin,
|
||||
|
@ -57,7 +59,7 @@ impl<'b> MultifileReader<'b> {
|
|||
// print an error at the time that the file is needed,
|
||||
// then move on the the next file.
|
||||
// This matches the behavior of the original `od`
|
||||
eprintln!("{}: '{}': {}", uucore::util_name(), fname, e);
|
||||
eprintln!("{}: {}: {}", uucore::util_name(), fname.maybe_quote(), e);
|
||||
self.any_err = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ use crate::partialreader::*;
|
|||
use crate::peekreader::*;
|
||||
use crate::prn_char::format_ascii_dump;
|
||||
use clap::{self, crate_version, AppSettings, Arg, ArgMatches};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::parse_size::ParseSizeError;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
|
@ -635,7 +636,7 @@ fn format_error_message(error: ParseSizeError, s: &str, option: &str) -> String
|
|||
// GNU's od echos affected flag, -N or --read-bytes (-j or --skip-bytes, etc.), depending user's selection
|
||||
// GNU's od does distinguish between "invalid (suffix in) argument"
|
||||
match error {
|
||||
ParseSizeError::ParseFailure(_) => format!("invalid --{} argument '{}'", option, s),
|
||||
ParseSizeError::SizeTooBig(_) => format!("--{} argument '{}' too large", option, s),
|
||||
ParseSizeError::ParseFailure(_) => format!("invalid --{} argument {}", option, s.quote()),
|
||||
ParseSizeError::SizeTooBig(_) => format!("--{} argument {} too large", option, s.quote()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// spell-checker:ignore formatteriteminfo docopt fvox fvoxw vals acdx
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
use crate::formatteriteminfo::FormatterItemInfo;
|
||||
use crate::prn_char::*;
|
||||
use crate::prn_float::*;
|
||||
|
@ -272,8 +274,9 @@ fn parse_type_string(params: &str) -> Result<Vec<ParsedFormatterItemInfo>, Strin
|
|||
while let Some(type_char) = ch {
|
||||
let type_char = format_type(type_char).ok_or_else(|| {
|
||||
format!(
|
||||
"unexpected char '{}' in format specification '{}'",
|
||||
type_char, params
|
||||
"unexpected char '{}' in format specification {}",
|
||||
type_char,
|
||||
params.quote()
|
||||
)
|
||||
})?;
|
||||
|
||||
|
@ -293,8 +296,9 @@ fn parse_type_string(params: &str) -> Result<Vec<ParsedFormatterItemInfo>, Strin
|
|||
if !decimal_size.is_empty() {
|
||||
byte_size = decimal_size.parse().map_err(|_| {
|
||||
format!(
|
||||
"invalid number '{}' in format specification '{}'",
|
||||
decimal_size, params
|
||||
"invalid number {} in format specification {}",
|
||||
decimal_size.quote(),
|
||||
params.quote()
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
@ -305,8 +309,9 @@ fn parse_type_string(params: &str) -> Result<Vec<ParsedFormatterItemInfo>, Strin
|
|||
|
||||
let ft = od_format_type(type_char, byte_size).ok_or_else(|| {
|
||||
format!(
|
||||
"invalid size '{}' in format specification '{}'",
|
||||
byte_size, params
|
||||
"invalid size '{}' in format specification {}",
|
||||
byte_size,
|
||||
params.quote()
|
||||
)
|
||||
})?;
|
||||
formats.push(ParsedFormatterItemInfo::new(ft, show_ascii_dump));
|
||||
|
|
|
@ -15,6 +15,7 @@ extern crate uucore;
|
|||
use clap::{crate_version, App, Arg};
|
||||
use std::fs;
|
||||
use std::io::{ErrorKind, Write};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
// operating mode
|
||||
|
@ -153,10 +154,10 @@ fn check_basic(path: &[String]) -> bool {
|
|||
if component_len > POSIX_NAME_MAX {
|
||||
writeln!(
|
||||
&mut std::io::stderr(),
|
||||
"limit {} exceeded by length {} of file name component '{}'",
|
||||
"limit {} exceeded by length {} of file name component {}",
|
||||
POSIX_NAME_MAX,
|
||||
component_len,
|
||||
p
|
||||
p.quote()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -175,8 +176,8 @@ fn check_extra(path: &[String]) -> bool {
|
|||
if p.starts_with('-') {
|
||||
writeln!(
|
||||
&mut std::io::stderr(),
|
||||
"leading hyphen in file name component '{}'",
|
||||
p
|
||||
"leading hyphen in file name component {}",
|
||||
p.quote()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -197,10 +198,10 @@ fn check_default(path: &[String]) -> bool {
|
|||
if total_len > libc::PATH_MAX as usize {
|
||||
writeln!(
|
||||
&mut std::io::stderr(),
|
||||
"limit {} exceeded by length {} of file name '{}'",
|
||||
"limit {} exceeded by length {} of file name {}",
|
||||
libc::PATH_MAX,
|
||||
total_len,
|
||||
joined_path
|
||||
joined_path.quote()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -210,10 +211,10 @@ fn check_default(path: &[String]) -> bool {
|
|||
if component_len > libc::FILENAME_MAX as usize {
|
||||
writeln!(
|
||||
&mut std::io::stderr(),
|
||||
"limit {} exceeded by length {} of file name component '{}'",
|
||||
"limit {} exceeded by length {} of file name component {}",
|
||||
libc::FILENAME_MAX,
|
||||
component_len,
|
||||
p
|
||||
p.quote()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -246,9 +247,9 @@ fn check_portable_chars(path_segment: &str) -> bool {
|
|||
let invalid = path_segment[i..].chars().next().unwrap();
|
||||
writeln!(
|
||||
&mut std::io::stderr(),
|
||||
"nonportable character '{}' in file name component '{}'",
|
||||
"nonportable character '{}' in file name component {}",
|
||||
invalid,
|
||||
path_segment
|
||||
path_segment.quote()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ use std::io::{stdin, stdout, BufRead, BufReader, Lines, Read, Stdout, Write};
|
|||
#[cfg(unix)]
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
type IOError = std::io::Error;
|
||||
|
||||
const NAME: &str = "pr";
|
||||
|
@ -517,7 +519,7 @@ fn parse_usize(matches: &Matches, opt: &str) -> Option<Result<usize, PrError>> {
|
|||
let i = value_to_parse.0;
|
||||
let option = value_to_parse.1;
|
||||
i.parse().map_err(|_e| {
|
||||
PrError::EncounteredErrors(format!("invalid {} argument '{}'", option, i))
|
||||
PrError::EncounteredErrors(format!("invalid {} argument {}", option, i.quote()))
|
||||
})
|
||||
};
|
||||
matches
|
||||
|
@ -619,7 +621,7 @@ fn build_options(
|
|||
let unparsed_num = i.get(1).unwrap().as_str().trim();
|
||||
let x: Vec<_> = unparsed_num.split(':').collect();
|
||||
x[0].to_string().parse::<usize>().map_err(|_e| {
|
||||
PrError::EncounteredErrors(format!("invalid {} argument '{}'", "+", unparsed_num))
|
||||
PrError::EncounteredErrors(format!("invalid {} argument {}", "+", unparsed_num.quote()))
|
||||
})
|
||||
}) {
|
||||
Some(res) => res?,
|
||||
|
@ -633,7 +635,11 @@ fn build_options(
|
|||
.map(|unparsed_num| {
|
||||
let x: Vec<_> = unparsed_num.split(':').collect();
|
||||
x[1].to_string().parse::<usize>().map_err(|_e| {
|
||||
PrError::EncounteredErrors(format!("invalid {} argument '{}'", "+", unparsed_num))
|
||||
PrError::EncounteredErrors(format!(
|
||||
"invalid {} argument {}",
|
||||
"+",
|
||||
unparsed_num.quote()
|
||||
))
|
||||
})
|
||||
}) {
|
||||
Some(res) => Some(res?),
|
||||
|
@ -643,7 +649,10 @@ fn build_options(
|
|||
let invalid_pages_map = |i: String| {
|
||||
let unparsed_value = matches.opt_str(options::PAGE_RANGE_OPTION).unwrap();
|
||||
i.parse::<usize>().map_err(|_e| {
|
||||
PrError::EncounteredErrors(format!("invalid --pages argument '{}'", unparsed_value))
|
||||
PrError::EncounteredErrors(format!(
|
||||
"invalid --pages argument {}",
|
||||
unparsed_value.quote()
|
||||
))
|
||||
})
|
||||
};
|
||||
|
||||
|
@ -741,7 +750,7 @@ fn build_options(
|
|||
let start_column_option = match re_col.captures(&free_args).map(|i| {
|
||||
let unparsed_num = i.get(1).unwrap().as_str().trim();
|
||||
unparsed_num.parse::<usize>().map_err(|_e| {
|
||||
PrError::EncounteredErrors(format!("invalid {} argument '{}'", "-", unparsed_num))
|
||||
PrError::EncounteredErrors(format!("invalid {} argument {}", "-", unparsed_num.quote()))
|
||||
})
|
||||
}) {
|
||||
Some(res) => Some(res?),
|
||||
|
|
|
@ -2,20 +2,11 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) bslice
|
||||
|
||||
use std::env;
|
||||
use std::io::{stderr, stdout, Write};
|
||||
use std::io::{stdout, Write};
|
||||
|
||||
pub const EXIT_OK: i32 = 0;
|
||||
pub const EXIT_ERR: i32 = 1;
|
||||
|
||||
pub fn err_msg(msg: &str) {
|
||||
let exe_path = match env::current_exe() {
|
||||
Ok(p) => p.to_string_lossy().into_owned(),
|
||||
_ => String::from(""),
|
||||
};
|
||||
writeln!(&mut stderr(), "{}: {}", exe_path, msg).unwrap();
|
||||
}
|
||||
|
||||
// by default stdout only flushes
|
||||
// to console when a newline is passed.
|
||||
pub fn flush_char(c: char) {
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
use itertools::put_back_n;
|
||||
use std::iter::Peekable;
|
||||
use std::slice::Iter;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::show_error;
|
||||
|
||||
use crate::cli;
|
||||
use crate::tokenize::sub::Sub;
|
||||
use crate::tokenize::token::{Token, Tokenizer};
|
||||
use crate::tokenize::unescaped_text::UnescapedText;
|
||||
|
@ -19,10 +20,10 @@ pub struct Memo {
|
|||
}
|
||||
|
||||
fn warn_excess_args(first_arg: &str) {
|
||||
cli::err_msg(&format!(
|
||||
"warning: ignoring excess arguments, starting with '{}'",
|
||||
first_arg
|
||||
));
|
||||
show_error!(
|
||||
"warning: ignoring excess arguments, starting with {}",
|
||||
first_arg.quote()
|
||||
);
|
||||
}
|
||||
|
||||
impl Memo {
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
|
||||
use itertools::{put_back_n, PutBackN};
|
||||
use std::str::Chars;
|
||||
use uucore::{display::Quotable, show_error};
|
||||
|
||||
use super::format_field::FormatField;
|
||||
|
||||
use crate::cli;
|
||||
|
||||
// contains the rough ingredients to final
|
||||
// output for a number, organized together
|
||||
// to allow for easy generalization of output manipulation
|
||||
|
@ -66,5 +65,5 @@ pub fn get_it_at(offset: usize, str_in: &str) -> PutBackN<Chars> {
|
|||
// TODO: put this somewhere better
|
||||
pub fn warn_incomplete_conv(pf_arg: &str) {
|
||||
// important: keep println here not print
|
||||
cli::err_msg(&format!("{}: value not completely converted", pf_arg))
|
||||
show_error!("{}: value not completely converted", pf_arg.maybe_quote());
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
use std::env;
|
||||
use std::vec::Vec;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
use uucore::show_error;
|
||||
|
||||
use super::format_field::{FieldType, FormatField};
|
||||
use super::formatter::{Base, FormatPrimitive, Formatter, InitialPrefix};
|
||||
use super::formatters::cninetyninehexfloatf::CninetyNineHexFloatf;
|
||||
|
@ -15,11 +18,9 @@ use super::formatters::floatf::Floatf;
|
|||
use super::formatters::intf::Intf;
|
||||
use super::formatters::scif::Scif;
|
||||
|
||||
use crate::cli;
|
||||
|
||||
pub fn warn_expected_numeric(pf_arg: &str) {
|
||||
// important: keep println here not print
|
||||
cli::err_msg(&format!("{}: expected a numeric value", pf_arg));
|
||||
show_error!("{}: expected a numeric value", pf_arg.maybe_quote());
|
||||
}
|
||||
|
||||
// when character constant arguments have excess characters
|
||||
|
@ -29,11 +30,11 @@ fn warn_char_constant_ign(remaining_bytes: Vec<u8>) {
|
|||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
if let env::VarError::NotPresent = e {
|
||||
cli::err_msg(&format!(
|
||||
show_error!(
|
||||
"warning: {:?}: character(s) following character \
|
||||
constant have been ignored",
|
||||
&*remaining_bytes
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::iter::Peekable;
|
|||
use std::process::exit;
|
||||
use std::slice::Iter;
|
||||
use std::str::Chars;
|
||||
use uucore::show_error;
|
||||
// use std::collections::HashSet;
|
||||
|
||||
use super::num_format::format_field::{FieldType, FormatField};
|
||||
|
@ -19,7 +20,7 @@ use super::unescaped_text::UnescapedText;
|
|||
use crate::cli;
|
||||
|
||||
fn err_conv(sofar: &str) {
|
||||
cli::err_msg(&format!("%{}: invalid conversion specification", sofar));
|
||||
show_error!("%{}: invalid conversion specification", sofar);
|
||||
exit(cli::EXIT_ERR);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::collections::{BTreeSet, HashMap, HashSet};
|
|||
use std::default::Default;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static NAME: &str = "ptx";
|
||||
|
@ -292,7 +293,11 @@ fn create_word_set(config: &Config, filter: &WordFilter, file_map: &FileMap) ->
|
|||
|
||||
fn get_reference(config: &Config, word_ref: &WordRef, line: &str, context_reg: &Regex) -> String {
|
||||
if config.auto_ref {
|
||||
format!("{}:{}", word_ref.filename, word_ref.local_line_nr + 1)
|
||||
format!(
|
||||
"{}:{}",
|
||||
word_ref.filename.maybe_quote(),
|
||||
word_ref.local_line_nr + 1
|
||||
)
|
||||
} else if config.input_ref {
|
||||
let (beg, end) = match context_reg.find(line) {
|
||||
Some(x) => (x.start(), x.end()),
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::fs;
|
||||
use std::io::{stdout, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};
|
||||
|
||||
const ABOUT: &str = "Print value of a symbolic link or canonical file name.";
|
||||
|
@ -71,10 +72,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
|
||||
if no_newline && files.len() > 1 && !silent {
|
||||
eprintln!(
|
||||
"{}: ignoring --no-newline with multiple arguments",
|
||||
uucore::util_name()
|
||||
);
|
||||
show_error!("ignoring --no-newline with multiple arguments");
|
||||
no_newline = false;
|
||||
}
|
||||
|
||||
|
@ -85,12 +83,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
Ok(path) => show(&path, no_newline, use_zero),
|
||||
Err(err) => {
|
||||
if verbose {
|
||||
eprintln!(
|
||||
"{}: {}: errno {}",
|
||||
uucore::util_name(),
|
||||
f,
|
||||
err.raw_os_error().unwrap()
|
||||
);
|
||||
show_error!("{}: errno {}", f.maybe_quote(), err.raw_os_error().unwrap());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -100,12 +93,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
Ok(path) => show(&path, no_newline, use_zero),
|
||||
Err(err) => {
|
||||
if verbose {
|
||||
eprintln!(
|
||||
"{}: {}: errno {:?}",
|
||||
uucore::util_name(),
|
||||
f,
|
||||
err.raw_os_error().unwrap()
|
||||
);
|
||||
show_error!("{}: errno {}", f.maybe_quote(), err.raw_os_error().unwrap());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,14 @@
|
|||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};
|
||||
use std::{
|
||||
io::{stdout, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use uucore::{
|
||||
display::{print_verbatim, Quotable},
|
||||
fs::{canonicalize, MissingHandling, ResolveMode},
|
||||
};
|
||||
|
||||
static ABOUT: &str = "print the resolved path";
|
||||
|
||||
|
@ -58,7 +64,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
for path in &paths {
|
||||
if let Err(e) = resolve_path(path, strip, zero, logical, can_mode) {
|
||||
if !quiet {
|
||||
show_error!("{}: {}", e, path.display());
|
||||
show_error!("{}: {}", path.maybe_quote(), e);
|
||||
}
|
||||
retcode = 1
|
||||
};
|
||||
|
@ -154,8 +160,9 @@ fn resolve_path(
|
|||
ResolveMode::Physical
|
||||
};
|
||||
let abs = canonicalize(p, can_mode, resolve)?;
|
||||
let line_ending = if zero { '\0' } else { '\n' };
|
||||
let line_ending = if zero { b'\0' } else { b'\n' };
|
||||
|
||||
print!("{}{}", abs.display(), line_ending);
|
||||
print_verbatim(&abs)?;
|
||||
stdout().write_all(&[line_ending])?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
use clap::{crate_version, App, Arg};
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::display::println_verbatim;
|
||||
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
|
@ -48,7 +49,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if !absto.as_path().starts_with(absbase.as_path())
|
||||
|| !absfrom.as_path().starts_with(absbase.as_path())
|
||||
{
|
||||
println!("{}", absto.display());
|
||||
println_verbatim(absto).unwrap();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.map(|x| result.push(x.as_os_str()))
|
||||
.last();
|
||||
|
||||
println!("{}", result.display());
|
||||
println_verbatim(result).unwrap();
|
||||
0
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::fs;
|
|||
use std::io::{stderr, stdin, BufRead, Write};
|
||||
use std::ops::BitOr;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::display::Quotable;
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy)]
|
||||
|
@ -236,7 +237,10 @@ fn remove(files: Vec<String>, options: Options) -> bool {
|
|||
// (e.g., permission), even rm -f should fail with
|
||||
// outputting the error, but there's no easy eay.
|
||||
if !options.force {
|
||||
show_error!("cannot remove '{}': No such file or directory", filename);
|
||||
show_error!(
|
||||
"cannot remove {}: No such file or directory",
|
||||
filename.quote()
|
||||
);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -263,13 +267,9 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
|||
// GNU compatibility (rm/fail-eacces.sh)
|
||||
// here, GNU doesn't use some kind of remove_dir_all
|
||||
// It will show directory+file
|
||||
show_error!(
|
||||
"cannot remove '{}': {}",
|
||||
path.display(),
|
||||
"Permission denied"
|
||||
);
|
||||
show_error!("cannot remove {}: {}", path.quote(), "Permission denied");
|
||||
} else {
|
||||
show_error!("cannot remove '{}': {}", path.display(), e);
|
||||
show_error!("cannot remove {}: {}", path.quote(), e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -287,7 +287,7 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
|||
}
|
||||
Err(e) => {
|
||||
had_err = true;
|
||||
show_error!("recursing in '{}': {}", path.display(), e);
|
||||
show_error!("recursing in {}: {}", path.quote(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,12 +299,12 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
|||
} else if options.dir && (!is_root || !options.preserve_root) {
|
||||
had_err = remove_dir(path, options).bitor(had_err);
|
||||
} else if options.recursive {
|
||||
show_error!("could not remove directory '{}'", path.display());
|
||||
show_error!("could not remove directory {}", path.quote());
|
||||
had_err = true;
|
||||
} else {
|
||||
show_error!(
|
||||
"cannot remove '{}': Is a directory", // GNU's rm error message does not include help
|
||||
path.display()
|
||||
"cannot remove {}: Is a directory", // GNU's rm error message does not include help
|
||||
path.quote()
|
||||
);
|
||||
had_err = true;
|
||||
}
|
||||
|
@ -325,36 +325,36 @@ fn remove_dir(path: &Path, options: &Options) -> bool {
|
|||
match fs::remove_dir(path) {
|
||||
Ok(_) => {
|
||||
if options.verbose {
|
||||
println!("removed directory '{}'", normalize(path).display());
|
||||
println!("removed directory {}", normalize(path).quote());
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == std::io::ErrorKind::PermissionDenied {
|
||||
// GNU compatibility (rm/fail-eacces.sh)
|
||||
show_error!(
|
||||
"cannot remove '{}': {}",
|
||||
path.display(),
|
||||
"cannot remove {}: {}",
|
||||
path.quote(),
|
||||
"Permission denied"
|
||||
);
|
||||
} else {
|
||||
show_error!("cannot remove '{}': {}", path.display(), e);
|
||||
show_error!("cannot remove {}: {}", path.quote(), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// directory can be read but is not empty
|
||||
show_error!("cannot remove '{}': Directory not empty", path.display());
|
||||
show_error!("cannot remove {}: Directory not empty", path.quote());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// called to remove a symlink_dir (windows) without "-r"/"-R" or "-d"
|
||||
show_error!("cannot remove '{}': Is a directory", path.display());
|
||||
show_error!("cannot remove {}: Is a directory", path.quote());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// GNU's rm shows this message if directory is empty but not readable
|
||||
show_error!("cannot remove '{}': Directory not empty", path.display());
|
||||
show_error!("cannot remove {}: Directory not empty", path.quote());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -372,19 +372,15 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
|||
match fs::remove_file(path) {
|
||||
Ok(_) => {
|
||||
if options.verbose {
|
||||
println!("removed '{}'", normalize(path).display());
|
||||
println!("removed {}", normalize(path).quote());
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == std::io::ErrorKind::PermissionDenied {
|
||||
// GNU compatibility (rm/fail-eacces.sh)
|
||||
show_error!(
|
||||
"cannot remove '{}': {}",
|
||||
path.display(),
|
||||
"Permission denied"
|
||||
);
|
||||
show_error!("cannot remove {}: {}", path.quote(), "Permission denied");
|
||||
} else {
|
||||
show_error!("cannot remove '{}': {}", path.display(), e);
|
||||
show_error!("cannot remove {}: {}", path.quote(), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -396,9 +392,9 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
|||
|
||||
fn prompt_file(path: &Path, is_dir: bool) -> bool {
|
||||
if is_dir {
|
||||
prompt(&(format!("rm: remove directory '{}'? ", path.display())))
|
||||
prompt(&(format!("rm: remove directory {}? ", path.quote())))
|
||||
} else {
|
||||
prompt(&(format!("rm: remove file '{}'? ", path.display())))
|
||||
prompt(&(format!("rm: remove file {}? ", path.quote())))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ use std::fmt::Write;
|
|||
use std::io;
|
||||
use std::str::Utf8Error;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
|
@ -31,7 +33,7 @@ pub(crate) enum Error {
|
|||
source: io::Error,
|
||||
},
|
||||
|
||||
#[error("{operation} failed on '{}'", .operand1.to_string_lossy())]
|
||||
#[error("{operation} failed on {}", .operand1.quote())]
|
||||
Io1 {
|
||||
operation: &'static str,
|
||||
operand1: OsString,
|
||||
|
|
|
@ -14,6 +14,7 @@ use num_traits::{Num, ToPrimitive};
|
|||
use std::cmp;
|
||||
use std::io::{stdout, Write};
|
||||
use std::str::FromStr;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT.";
|
||||
static OPT_SEPARATOR: &str = "separator";
|
||||
|
@ -115,14 +116,14 @@ impl FromStr for Number {
|
|||
}
|
||||
Err(_) => match s.parse::<f64>() {
|
||||
Ok(value) if value.is_nan() => Err(format!(
|
||||
"invalid 'not-a-number' argument: '{}'\nTry '{} --help' for more information.",
|
||||
s,
|
||||
"invalid 'not-a-number' argument: {}\nTry '{} --help' for more information.",
|
||||
s.quote(),
|
||||
uucore::execution_phrase(),
|
||||
)),
|
||||
Ok(value) => Ok(Number::F64(value)),
|
||||
Err(_) => Err(format!(
|
||||
"invalid floating point argument: '{}'\nTry '{} --help' for more information.",
|
||||
s,
|
||||
"invalid floating point argument: {}\nTry '{} --help' for more information.",
|
||||
s.quote(),
|
||||
uucore::execution_phrase(),
|
||||
)),
|
||||
},
|
||||
|
|
|
@ -18,12 +18,12 @@ use std::io;
|
|||
use std::io::prelude::*;
|
||||
use std::io::SeekFrom;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::{util_name, InvalidEncodingHandling};
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
static NAME: &str = "shred";
|
||||
const BLOCK_SIZE: usize = 512;
|
||||
const NAME_CHARSET: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.";
|
||||
|
||||
|
@ -281,7 +281,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
if !matches.is_present(options::FILE) {
|
||||
show_error!("Missing an argument");
|
||||
show_error!("For help, try '{} --help'", NAME);
|
||||
show_error!("For help, try '{} --help'", uucore::execution_phrase());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
Some(s) => match s.parse::<usize>() {
|
||||
Ok(u) => u,
|
||||
Err(_) => {
|
||||
errs.push(format!("invalid number of passes: '{}'", s));
|
||||
errs.push(format!("invalid number of passes: {}", s.quote()));
|
||||
0
|
||||
}
|
||||
},
|
||||
|
@ -414,7 +414,11 @@ fn get_size(size_str_opt: Option<String>) -> Option<u64> {
|
|||
let coefficient = match size_str.parse::<u64>() {
|
||||
Ok(u) => u,
|
||||
Err(_) => {
|
||||
println!("{}: {}: Invalid file size", NAME, size_str_opt.unwrap());
|
||||
println!(
|
||||
"{}: {}: Invalid file size",
|
||||
util_name(),
|
||||
size_str_opt.unwrap().maybe_quote()
|
||||
);
|
||||
exit!(1);
|
||||
}
|
||||
};
|
||||
|
@ -452,11 +456,11 @@ fn wipe_file(
|
|||
// Get these potential errors out of the way first
|
||||
let path: &Path = Path::new(path_str);
|
||||
if !path.exists() {
|
||||
show_error!("{}: No such file or directory", path.display());
|
||||
show_error!("{}: No such file or directory", path.maybe_quote());
|
||||
return;
|
||||
}
|
||||
if !path.is_file() {
|
||||
show_error!("{}: Not a file", path.display());
|
||||
show_error!("{}: Not a file", path.maybe_quote());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -520,7 +524,7 @@ fn wipe_file(
|
|||
let mut file: File = match OpenOptions::new().write(true).truncate(false).open(path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
show_error!("{}: failed to open for writing: {}", path.display(), e);
|
||||
show_error!("{}: failed to open for writing: {}", path.maybe_quote(), e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -535,8 +539,8 @@ fn wipe_file(
|
|||
if total_passes.to_string().len() == 1 {
|
||||
println!(
|
||||
"{}: {}: pass {}/{} ({})... ",
|
||||
NAME,
|
||||
path.display(),
|
||||
util_name(),
|
||||
path.maybe_quote(),
|
||||
i + 1,
|
||||
total_passes,
|
||||
pass_name
|
||||
|
@ -544,8 +548,8 @@ fn wipe_file(
|
|||
} else {
|
||||
println!(
|
||||
"{}: {}: pass {:2.0}/{:2.0} ({})... ",
|
||||
NAME,
|
||||
path.display(),
|
||||
util_name(),
|
||||
path.maybe_quote(),
|
||||
i + 1,
|
||||
total_passes,
|
||||
pass_name
|
||||
|
@ -556,7 +560,7 @@ fn wipe_file(
|
|||
match do_pass(&mut file, path, &mut generator, *pass_type, size) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
show_error!("{}: File write pass failed: {}", path.display(), e);
|
||||
show_error!("{}: File write pass failed: {}", path.maybe_quote(), e);
|
||||
}
|
||||
}
|
||||
// Ignore failed writes; just keep trying
|
||||
|
@ -567,7 +571,7 @@ fn wipe_file(
|
|||
match do_remove(path, path_str, verbose) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
show_error!("{}: failed to remove file: {}", path.display(), e);
|
||||
show_error!("{}: failed to remove file: {}", path.maybe_quote(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -622,9 +626,9 @@ fn wipe_name(orig_path: &Path, verbose: bool) -> Option<PathBuf> {
|
|||
if verbose {
|
||||
println!(
|
||||
"{}: {}: renamed to {}",
|
||||
NAME,
|
||||
last_path.display(),
|
||||
new_path.display()
|
||||
util_name(),
|
||||
last_path.maybe_quote(),
|
||||
new_path.quote()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -641,9 +645,9 @@ fn wipe_name(orig_path: &Path, verbose: bool) -> Option<PathBuf> {
|
|||
Err(e) => {
|
||||
println!(
|
||||
"{}: {}: Couldn't rename to {}: {}",
|
||||
NAME,
|
||||
last_path.display(),
|
||||
new_path.display(),
|
||||
util_name(),
|
||||
last_path.maybe_quote(),
|
||||
new_path.quote(),
|
||||
e
|
||||
);
|
||||
return None;
|
||||
|
@ -657,7 +661,7 @@ fn wipe_name(orig_path: &Path, verbose: bool) -> Option<PathBuf> {
|
|||
|
||||
fn do_remove(path: &Path, orig_filename: &str, verbose: bool) -> Result<(), io::Error> {
|
||||
if verbose {
|
||||
println!("{}: {}: removing", NAME, orig_filename);
|
||||
println!("{}: {}: removing", util_name(), orig_filename.maybe_quote());
|
||||
}
|
||||
|
||||
let renamed_path: Option<PathBuf> = wipe_name(path, verbose);
|
||||
|
@ -666,7 +670,7 @@ fn do_remove(path: &Path, orig_filename: &str, verbose: bool) -> Result<(), io::
|
|||
}
|
||||
|
||||
if verbose {
|
||||
println!("{}: {}: removed", NAME, orig_filename);
|
||||
println!("{}: {}: removed", util_name(), orig_filename.maybe_quote());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use rand::Rng;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
enum Mode {
|
||||
|
@ -76,7 +77,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
Some(count) => match count.parse::<usize>() {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
show_error!("invalid line count: '{}'", count);
|
||||
show_error!("invalid line count: {}", count.quote());
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
@ -185,13 +186,13 @@ fn read_input_file(filename: &str) -> Vec<u8> {
|
|||
} else {
|
||||
match File::open(filename) {
|
||||
Ok(f) => Box::new(f) as Box<dyn Read>,
|
||||
Err(e) => crash!(1, "failed to open '{}': {}", filename, e),
|
||||
Err(e) => crash!(1, "failed to open {}: {}", filename.quote(), e),
|
||||
}
|
||||
});
|
||||
|
||||
let mut data = Vec::new();
|
||||
if let Err(e) = file.read_to_end(&mut data) {
|
||||
crash!(1, "failed reading '{}': {}", filename, e)
|
||||
crash!(1, "failed reading {}: {}", filename.quote(), e)
|
||||
};
|
||||
|
||||
data
|
||||
|
@ -235,7 +236,7 @@ fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) {
|
|||
None => Box::new(stdout()) as Box<dyn Write>,
|
||||
Some(s) => match File::create(&s[..]) {
|
||||
Ok(f) => Box::new(f) as Box<dyn Write>,
|
||||
Err(e) => crash!(1, "failed to open '{}' for writing: {}", &s[..], e),
|
||||
Err(e) => crash!(1, "failed to open {} for writing: {}", s.quote(), e),
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -243,7 +244,7 @@ fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) {
|
|||
Some(r) => WrappedRng::RngFile(rand::rngs::adapter::ReadRng::new(
|
||||
match File::open(&r[..]) {
|
||||
Ok(f) => f,
|
||||
Err(e) => crash!(1, "failed to open random source '{}': {}", &r[..], e),
|
||||
Err(e) => crash!(1, "failed to open random source {}: {}", r.quote(), e),
|
||||
},
|
||||
)),
|
||||
None => WrappedRng::RngDefault(rand::thread_rng()),
|
||||
|
@ -288,14 +289,14 @@ fn shuf_bytes(input: &mut Vec<&[u8]>, opts: Options) {
|
|||
fn parse_range(input_range: &str) -> Result<(usize, usize), String> {
|
||||
let split: Vec<&str> = input_range.split('-').collect();
|
||||
if split.len() != 2 {
|
||||
Err(format!("invalid input range: '{}'", input_range))
|
||||
Err(format!("invalid input range: {}", input_range.quote()))
|
||||
} else {
|
||||
let begin = split[0]
|
||||
.parse::<usize>()
|
||||
.map_err(|_| format!("invalid input range: '{}'", split[0]))?;
|
||||
.map_err(|_| format!("invalid input range: {}", split[0].quote()))?;
|
||||
let end = split[1]
|
||||
.parse::<usize>()
|
||||
.map_err(|_| format!("invalid input range: '{}'", split[1]))?;
|
||||
.map_err(|_| format!("invalid input range: {}", split[1].quote()))?;
|
||||
Ok((begin, end + 1))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::str::Utf8Error;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{set_exit_code, strip_errno, UError, UResult, USimpleError, UUsageError};
|
||||
use uucore::parse_size::{parse_size, ParseSizeError};
|
||||
use uucore::version_cmp::version_cmp;
|
||||
|
@ -139,7 +140,7 @@ enum SortError {
|
|||
error: std::io::Error,
|
||||
},
|
||||
ReadFailed {
|
||||
path: String,
|
||||
path: PathBuf,
|
||||
error: std::io::Error,
|
||||
},
|
||||
ParseKeyError {
|
||||
|
@ -189,7 +190,7 @@ impl Display for SortError {
|
|||
write!(
|
||||
f,
|
||||
"{}:{}: disorder: {}",
|
||||
file.to_string_lossy(),
|
||||
file.maybe_quote(),
|
||||
line_number,
|
||||
line
|
||||
)
|
||||
|
@ -198,13 +199,23 @@ impl Display for SortError {
|
|||
}
|
||||
}
|
||||
SortError::OpenFailed { path, error } => {
|
||||
write!(f, "open failed: {}: {}", path, strip_errno(error))
|
||||
write!(
|
||||
f,
|
||||
"open failed: {}: {}",
|
||||
path.maybe_quote(),
|
||||
strip_errno(error)
|
||||
)
|
||||
}
|
||||
SortError::ParseKeyError { key, msg } => {
|
||||
write!(f, "failed to parse key `{}`: {}", key, msg)
|
||||
write!(f, "failed to parse key {}: {}", key.quote(), msg)
|
||||
}
|
||||
SortError::ReadFailed { path, error } => {
|
||||
write!(f, "cannot read: {}: {}", path, strip_errno(error))
|
||||
write!(
|
||||
f,
|
||||
"cannot read: {}: {}",
|
||||
path.maybe_quote(),
|
||||
strip_errno(error)
|
||||
)
|
||||
}
|
||||
SortError::OpenTmpFileFailed { error } => {
|
||||
write!(f, "failed to open temporary file: {}", strip_errno(error))
|
||||
|
@ -213,7 +224,7 @@ impl Display for SortError {
|
|||
write!(f, "couldn't execute compress program: errno {}", code)
|
||||
}
|
||||
SortError::CompressProgTerminatedAbnormally { prog } => {
|
||||
write!(f, "'{}' terminated abnormally", prog)
|
||||
write!(f, "{} terminated abnormally", prog.quote())
|
||||
}
|
||||
SortError::TmpDirCreationFailed => write!(f, "could not create temporary directory"),
|
||||
SortError::Uft8Error { error } => write!(f, "{}", error),
|
||||
|
@ -1179,7 +1190,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
if let Some(n_merge) = matches.value_of(options::BATCH_SIZE) {
|
||||
settings.merge_batch_size = n_merge.parse().map_err(|_| {
|
||||
UUsageError::new(2, format!("invalid --batch-size argument '{}'", n_merge))
|
||||
UUsageError::new(
|
||||
2,
|
||||
format!("invalid --batch-size argument {}", n_merge.quote()),
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
||||
|
@ -1211,23 +1225,30 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
} else if settings.check && files.len() != 1 {
|
||||
return Err(UUsageError::new(
|
||||
2,
|
||||
format!(
|
||||
"extra operand `{}' not allowed with -c",
|
||||
files[1].to_string_lossy()
|
||||
),
|
||||
format!("extra operand {} not allowed with -c", files[1].quote()),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(arg) = matches.args.get(options::SEPARATOR) {
|
||||
let separator = arg.vals[0].to_string_lossy();
|
||||
let mut separator = separator.as_ref();
|
||||
let mut separator = arg.vals[0].to_str().ok_or_else(|| {
|
||||
UUsageError::new(
|
||||
2,
|
||||
format!("separator is not valid unicode: {}", arg.vals[0].quote()),
|
||||
)
|
||||
})?;
|
||||
if separator == "\\0" {
|
||||
separator = "\0";
|
||||
}
|
||||
// This rejects non-ASCII codepoints, but perhaps we don't have to.
|
||||
// On the other hand GNU accepts any single byte, valid unicode or not.
|
||||
// (Supporting multi-byte chars would require changes in tokenize_with_separator().)
|
||||
if separator.len() != 1 {
|
||||
return Err(UUsageError::new(
|
||||
2,
|
||||
"separator must be exactly one character long",
|
||||
format!(
|
||||
"separator must be exactly one character long: {}",
|
||||
separator.quote()
|
||||
),
|
||||
));
|
||||
}
|
||||
settings.separator = Some(separator.chars().next().unwrap())
|
||||
|
@ -1816,7 +1837,7 @@ fn open(path: impl AsRef<OsStr>) -> UResult<Box<dyn Read + Send>> {
|
|||
match File::open(path) {
|
||||
Ok(f) => Ok(Box::new(f) as Box<dyn Read + Send>),
|
||||
Err(error) => Err(SortError::ReadFailed {
|
||||
path: path.to_string_lossy().to_string(),
|
||||
path: path.to_owned(),
|
||||
error,
|
||||
}
|
||||
.into()),
|
||||
|
@ -1828,8 +1849,8 @@ fn format_error_message(error: ParseSizeError, s: &str, option: &str) -> String
|
|||
// GNU's sort echos affected flag, -S or --buffer-size, depending user's selection
|
||||
// GNU's sort does distinguish between "invalid (suffix in) argument"
|
||||
match error {
|
||||
ParseSizeError::ParseFailure(_) => format!("invalid --{} argument '{}'", option, s),
|
||||
ParseSizeError::SizeTooBig(_) => format!("--{} argument '{}' too large", option, s),
|
||||
ParseSizeError::ParseFailure(_) => format!("invalid --{} argument {}", option, s.quote()),
|
||||
ParseSizeError::SizeTooBig(_) => format!("--{} argument {} too large", option, s.quote()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ use std::fs::File;
|
|||
use std::io::{stdin, BufRead, BufReader, BufWriter, Read, Write};
|
||||
use std::path::Path;
|
||||
use std::{char, fs::remove_file};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::parse_size::parse_size;
|
||||
|
||||
static OPT_BYTES: &str = "bytes";
|
||||
|
@ -238,7 +239,11 @@ impl LineSplitter {
|
|||
fn new(settings: &Settings) -> LineSplitter {
|
||||
LineSplitter {
|
||||
lines_per_split: settings.strategy_param.parse().unwrap_or_else(|_| {
|
||||
crash!(1, "invalid number of lines: '{}'", settings.strategy_param)
|
||||
crash!(
|
||||
1,
|
||||
"invalid number of lines: {}",
|
||||
settings.strategy_param.quote()
|
||||
)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -373,8 +378,8 @@ fn split(settings: &Settings) -> i32 {
|
|||
let r = File::open(Path::new(&settings.input)).unwrap_or_else(|_| {
|
||||
crash!(
|
||||
1,
|
||||
"cannot open '{}' for reading: No such file or directory",
|
||||
settings.input
|
||||
"cannot open {} for reading: No such file or directory",
|
||||
settings.input.quote()
|
||||
)
|
||||
});
|
||||
Box::new(r) as Box<dyn Read>
|
||||
|
@ -383,7 +388,7 @@ fn split(settings: &Settings) -> i32 {
|
|||
let mut splitter: Box<dyn Splitter> = match settings.strategy.as_str() {
|
||||
s if s == OPT_LINES => Box::new(LineSplitter::new(settings)),
|
||||
s if (s == OPT_BYTES || s == OPT_LINE_BYTES) => Box::new(ByteSplitter::new(settings)),
|
||||
a => crash!(1, "strategy {} not supported", a),
|
||||
a => crash!(1, "strategy {} not supported", a.quote()),
|
||||
};
|
||||
|
||||
let mut fileno = 0;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::entries;
|
||||
use uucore::fs::display_permissions;
|
||||
use uucore::fsext::{
|
||||
|
@ -24,7 +25,7 @@ use std::{cmp, fs, iter};
|
|||
macro_rules! check_bound {
|
||||
($str: ident, $bound:expr, $beg: expr, $end: expr) => {
|
||||
if $end >= $bound {
|
||||
return Err(format!("'{}': invalid directive", &$str[$beg..$end]));
|
||||
return Err(format!("{}: invalid directive", $str[$beg..$end].quote()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -652,11 +653,7 @@ impl Stater {
|
|||
return 1;
|
||||
}
|
||||
};
|
||||
arg = format!(
|
||||
"`{}' -> `{}'",
|
||||
file,
|
||||
dst.to_string_lossy()
|
||||
);
|
||||
arg = format!("{} -> {}", file.quote(), dst.quote());
|
||||
} else {
|
||||
arg = file.to_string();
|
||||
}
|
||||
|
@ -750,7 +747,7 @@ impl Stater {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
show_error!("cannot stat '{}': {}", file, e);
|
||||
show_error!("cannot stat {}: {}", file.quote(), e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -843,7 +840,11 @@ impl Stater {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
show_error!("cannot read file system information for '{}': {}", file, e);
|
||||
show_error!(
|
||||
"cannot read file system information for {}: {}",
|
||||
file.quote(),
|
||||
e
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use std::fs::File;
|
||||
use std::io::{stdin, Read, Result};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static NAME: &str = "sum";
|
||||
|
@ -118,7 +119,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let reader = match open(file) {
|
||||
Ok(f) => f,
|
||||
Err(error) => {
|
||||
show_error!("'{}' {}", file, error);
|
||||
show_error!("{}: {}", file.maybe_quote(), error);
|
||||
exit_code = 2;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ extern crate uucore;
|
|||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
static EXIT_ERR: i32 = 1;
|
||||
|
||||
|
@ -175,7 +176,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
for f in &files {
|
||||
if !Path::new(&f).exists() {
|
||||
crash!(EXIT_ERR, "cannot stat '{}': No such file or directory", f);
|
||||
crash!(
|
||||
EXIT_ERR,
|
||||
"cannot stat {}: No such file or directory",
|
||||
f.quote()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ use clap::{crate_version, App, Arg};
|
|||
use memchr::memmem;
|
||||
use std::io::{stdin, stdout, BufReader, Read, Write};
|
||||
use std::{fs::File, path::Path};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static NAME: &str = "tac";
|
||||
|
@ -141,11 +142,11 @@ fn tac(filenames: Vec<String>, before: bool, _: bool, separator: &str) -> i32 {
|
|||
let path = Path::new(filename);
|
||||
if path.is_dir() || path.metadata().is_err() {
|
||||
if path.is_dir() {
|
||||
show_error!("{}: read error: Invalid argument", filename);
|
||||
show_error!("{}: read error: Invalid argument", filename.maybe_quote());
|
||||
} else {
|
||||
show_error!(
|
||||
"failed to open '{}' for reading: No such file or directory",
|
||||
filename
|
||||
"failed to open {} for reading: No such file or directory",
|
||||
filename.quote()
|
||||
);
|
||||
}
|
||||
exit_code = 1;
|
||||
|
@ -154,7 +155,7 @@ fn tac(filenames: Vec<String>, before: bool, _: bool, separator: &str) -> i32 {
|
|||
match File::open(path) {
|
||||
Ok(f) => Box::new(f) as Box<dyn Read>,
|
||||
Err(e) => {
|
||||
show_error!("failed to open '{}' for reading: {}", filename, e);
|
||||
show_error!("failed to open {} for reading: {}", filename.quote(), e);
|
||||
exit_code = 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -163,7 +164,7 @@ fn tac(filenames: Vec<String>, before: bool, _: bool, separator: &str) -> i32 {
|
|||
|
||||
let mut data = Vec::new();
|
||||
if let Err(e) = file.read_to_end(&mut data) {
|
||||
show_error!("failed to read '{}': {}", filename, e);
|
||||
show_error!("failed to read {}: {}", filename.quote(), e);
|
||||
exit_code = 1;
|
||||
continue;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,8 @@ use clap::{crate_version, App, Arg};
|
|||
use retain_mut::RetainMut;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{copy, sink, stdin, stdout, Error, ErrorKind, Read, Result, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use uucore::display::Quotable;
|
||||
|
||||
#[cfg(unix)]
|
||||
use uucore::libc;
|
||||
|
@ -167,7 +168,7 @@ impl Write for MultiWriter {
|
|||
let result = writer.write_all(buf);
|
||||
match result {
|
||||
Err(f) => {
|
||||
show_error!("{}: {}", writer.name, f.to_string());
|
||||
show_error!("{}: {}", writer.name.maybe_quote(), f);
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
|
@ -181,7 +182,7 @@ impl Write for MultiWriter {
|
|||
let result = writer.flush();
|
||||
match result {
|
||||
Err(f) => {
|
||||
show_error!("{}: {}", writer.name, f.to_string());
|
||||
show_error!("{}: {}", writer.name.maybe_quote(), f);
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
|
@ -214,7 +215,7 @@ impl Read for NamedReader {
|
|||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
match self.inner.read(buf) {
|
||||
Err(f) => {
|
||||
show_error!("{}: {}", Path::new("stdin").display(), f.to_string());
|
||||
show_error!("stdin: {}", f);
|
||||
Err(f)
|
||||
}
|
||||
okay => okay,
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
use std::ffi::OsString;
|
||||
use std::iter::Peekable;
|
||||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
/// Represents one of the binary comparison operators for strings, integers, or files
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Operator {
|
||||
|
@ -43,7 +45,8 @@ impl Symbol {
|
|||
/// Returns Symbol::None in place of None
|
||||
fn new(token: Option<OsString>) -> Symbol {
|
||||
match token {
|
||||
Some(s) => match s.to_string_lossy().as_ref() {
|
||||
Some(s) => match s.to_str() {
|
||||
Some(t) => match t {
|
||||
"(" => Symbol::LParen,
|
||||
"!" => Symbol::Bang,
|
||||
"-a" | "-o" => Symbol::BoolOp(s),
|
||||
|
@ -57,6 +60,8 @@ impl Symbol {
|
|||
}
|
||||
_ => Symbol::Literal(s),
|
||||
},
|
||||
None => Symbol::Literal(s),
|
||||
},
|
||||
None => Symbol::None,
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +396,7 @@ impl Parser {
|
|||
self.expr();
|
||||
|
||||
match self.tokens.next() {
|
||||
Some(token) => Err(format!("extra argument '{}'", token.to_string_lossy())),
|
||||
Some(token) => Err(format!("extra argument {}", token.quote())),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ mod parser;
|
|||
use clap::{crate_version, App, AppSettings};
|
||||
use parser::{parse, Operator, Symbol, UnaryOperator};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
use uucore::{display::Quotable, show_error};
|
||||
|
||||
const USAGE: &str = "test EXPRESSION
|
||||
or: test
|
||||
|
@ -93,10 +93,7 @@ pub fn uu_app() -> App<'static, 'static> {
|
|||
|
||||
pub fn uumain(mut args: impl uucore::Args) -> i32 {
|
||||
let program = args.next().unwrap_or_else(|| OsString::from("test"));
|
||||
let binary_name = Path::new(&program)
|
||||
.file_name()
|
||||
.unwrap_or_else(|| OsStr::new("test"))
|
||||
.to_string_lossy();
|
||||
let binary_name = uucore::util_name();
|
||||
let mut args: Vec<_> = args.collect();
|
||||
|
||||
if binary_name.ends_with('[') {
|
||||
|
@ -116,8 +113,8 @@ pub fn uumain(mut args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
// If invoked via name '[', matching ']' must be in the last arg
|
||||
let last = args.pop();
|
||||
if last != Some(OsString::from("]")) {
|
||||
eprintln!("[: missing ']'");
|
||||
if last.as_deref() != Some(OsStr::new("]")) {
|
||||
show_error!("missing ']'");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +130,7 @@ pub fn uumain(mut args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("test: {}", e);
|
||||
show_error!("{}", e);
|
||||
2
|
||||
}
|
||||
}
|
||||
|
@ -190,11 +187,11 @@ fn eval(stack: &mut Vec<Symbol>) -> Result<bool, String> {
|
|||
})
|
||||
}
|
||||
Some(Symbol::UnaryOp(UnaryOperator::FiletestOp(op))) => {
|
||||
let op = op.to_string_lossy();
|
||||
let op = op.to_str().unwrap();
|
||||
|
||||
let f = pop_literal!();
|
||||
|
||||
Ok(match op.as_ref() {
|
||||
Ok(match op {
|
||||
"-b" => path(&f, PathCondition::BlockSpecial),
|
||||
"-c" => path(&f, PathCondition::CharacterSpecial),
|
||||
"-d" => path(&f, PathCondition::Directory),
|
||||
|
@ -231,31 +228,33 @@ fn eval(stack: &mut Vec<Symbol>) -> Result<bool, String> {
|
|||
}
|
||||
|
||||
fn integers(a: &OsStr, b: &OsStr, op: &OsStr) -> Result<bool, String> {
|
||||
let format_err = |value| format!("invalid integer '{}'", value);
|
||||
let format_err = |value: &OsStr| format!("invalid integer {}", value.quote());
|
||||
|
||||
let a = a.to_string_lossy();
|
||||
let a: i64 = a.parse().map_err(|_| format_err(a))?;
|
||||
let a: i64 = a
|
||||
.to_str()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.ok_or_else(|| format_err(a))?;
|
||||
|
||||
let b = b.to_string_lossy();
|
||||
let b: i64 = b.parse().map_err(|_| format_err(b))?;
|
||||
let b: i64 = b
|
||||
.to_str()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.ok_or_else(|| format_err(b))?;
|
||||
|
||||
let operator = op.to_string_lossy();
|
||||
Ok(match operator.as_ref() {
|
||||
"-eq" => a == b,
|
||||
"-ne" => a != b,
|
||||
"-gt" => a > b,
|
||||
"-ge" => a >= b,
|
||||
"-lt" => a < b,
|
||||
"-le" => a <= b,
|
||||
_ => return Err(format!("unknown operator '{}'", operator)),
|
||||
Ok(match op.to_str() {
|
||||
Some("-eq") => a == b,
|
||||
Some("-ne") => a != b,
|
||||
Some("-gt") => a > b,
|
||||
Some("-ge") => a >= b,
|
||||
Some("-lt") => a < b,
|
||||
Some("-le") => a <= b,
|
||||
_ => return Err(format!("unknown operator {}", op.quote())),
|
||||
})
|
||||
}
|
||||
|
||||
fn isatty(fd: &OsStr) -> Result<bool, String> {
|
||||
let fd = fd.to_string_lossy();
|
||||
|
||||
fd.parse()
|
||||
.map_err(|_| format!("invalid integer '{}'", fd))
|
||||
fd.to_str()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.ok_or_else(|| format!("invalid integer {}", fd.quote()))
|
||||
.map(|i| {
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
unsafe {
|
||||
|
|
|
@ -16,6 +16,7 @@ use clap::{crate_version, App, AppSettings, Arg};
|
|||
use std::io::ErrorKind;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::time::Duration;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::process::ChildExt;
|
||||
use uucore::signals::{signal_by_name_or_value, signal_name_by_value};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
@ -61,7 +62,7 @@ impl Config {
|
|||
let signal_result = signal_by_name_or_value(signal_);
|
||||
match signal_result {
|
||||
None => {
|
||||
unreachable!("invalid signal '{}'", signal_);
|
||||
unreachable!("invalid signal {}", signal_.quote());
|
||||
}
|
||||
Some(signal_value) => signal_value,
|
||||
}
|
||||
|
@ -216,9 +217,9 @@ fn timeout(
|
|||
Ok(None) => {
|
||||
if verbose {
|
||||
show_error!(
|
||||
"sending signal {} to command '{}'",
|
||||
"sending signal {} to command {}",
|
||||
signal_name_by_value(signal).unwrap(),
|
||||
cmd[0]
|
||||
cmd[0].quote()
|
||||
);
|
||||
}
|
||||
crash_if_err!(ERR_EXIT_STATUS, process.send_signal(signal));
|
||||
|
@ -233,7 +234,7 @@ fn timeout(
|
|||
}
|
||||
Ok(None) => {
|
||||
if verbose {
|
||||
show_error!("sending signal KILL to command '{}'", cmd[0]);
|
||||
show_error!("sending signal KILL to command {}", cmd[0].quote());
|
||||
}
|
||||
crash_if_err!(
|
||||
ERR_EXIT_STATUS,
|
||||
|
|
|
@ -17,6 +17,7 @@ use clap::{crate_version, App, Arg, ArgGroup};
|
|||
use filetime::*;
|
||||
use std::fs::{self, File};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
||||
|
||||
static ABOUT: &str = "Update the access and modification times of each FILE to the current time.";
|
||||
|
@ -82,7 +83,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
}
|
||||
|
||||
if let Err(e) = File::create(path) {
|
||||
show!(e.map_err_context(|| format!("cannot touch '{}'", path.display())));
|
||||
show!(e.map_err_context(|| format!("cannot touch {}", path.quote())));
|
||||
continue;
|
||||
};
|
||||
|
||||
|
@ -122,7 +123,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
} else {
|
||||
filetime::set_file_times(path, atime, mtime)
|
||||
}
|
||||
.map_err_context(|| format!("setting times of '{}'", path.display()))?;
|
||||
.map_err_context(|| format!("setting times of {}", path.quote()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -209,7 +210,7 @@ fn stat(path: &Path, follow: bool) -> UResult<(FileTime, FileTime)> {
|
|||
} else {
|
||||
fs::metadata(path)
|
||||
}
|
||||
.map_err_context(|| format!("failed to get attributes of '{}'", path.display()))?;
|
||||
.map_err_context(|| format!("failed to get attributes of {}", path.quote()))?;
|
||||
|
||||
Ok((
|
||||
FileTime::from_last_access_time(&metadata),
|
||||
|
@ -249,11 +250,16 @@ fn parse_timestamp(s: &str) -> UResult<FileTime> {
|
|||
10 => ("%y%m%d%H%M", s.to_owned()),
|
||||
11 => ("%Y%m%d%H%M.%S", format!("{}{}", now.tm_year + 1900, s)),
|
||||
8 => ("%Y%m%d%H%M", format!("{}{}", now.tm_year + 1900, s)),
|
||||
_ => return Err(USimpleError::new(1, format!("invalid date format '{}'", s))),
|
||||
_ => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("invalid date format {}", s.quote()),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let tm = time::strptime(&ts, format)
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid date format '{}'", s)))?;
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid date format {}", s.quote())))?;
|
||||
|
||||
let mut local = to_local(tm);
|
||||
local.tm_isdst = -1;
|
||||
|
@ -269,7 +275,10 @@ fn parse_timestamp(s: &str) -> UResult<FileTime> {
|
|||
};
|
||||
let tm2 = time::at(ts);
|
||||
if tm.tm_hour != tm2.tm_hour {
|
||||
return Err(USimpleError::new(1, format!("invalid date format '{}'", s)));
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("invalid date format {}", s.quote()),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ft)
|
||||
|
|
|
@ -21,7 +21,7 @@ use fnv::FnvHashMap;
|
|||
use std::io::{stdin, stdout, BufRead, BufWriter, Write};
|
||||
|
||||
use crate::expand::ExpandSet;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
use uucore::{display::Quotable, InvalidEncodingHandling};
|
||||
|
||||
static ABOUT: &str = "translate or delete characters";
|
||||
|
||||
|
@ -271,8 +271,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
if !(delete_flag || squeeze_flag) && sets.len() < 2 {
|
||||
show_error!(
|
||||
"missing operand after '{}'\nTry '{} --help' for more information.",
|
||||
sets[0],
|
||||
"missing operand after {}\nTry '{} --help' for more information.",
|
||||
sets[0].quote(),
|
||||
uucore::execution_phrase()
|
||||
);
|
||||
return 1;
|
||||
|
|
|
@ -15,6 +15,7 @@ use std::convert::TryFrom;
|
|||
use std::fs::{metadata, OpenOptions};
|
||||
use std::io::ErrorKind;
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::parse_size::{parse_size, ParseSizeError};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
|
@ -120,8 +121,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let reference = matches.value_of(options::REFERENCE).map(String::from);
|
||||
crash!(
|
||||
1,
|
||||
"cannot stat '{}': No such file or directory",
|
||||
reference.unwrap_or_else(|| "".to_string())
|
||||
"cannot stat {}: No such file or directory",
|
||||
reference.as_deref().unwrap_or("").quote()
|
||||
); // TODO: fix '--no-create' see test_reference and test_truncate_bytes_size
|
||||
}
|
||||
_ => crash!(1, "{}", e.to_string()),
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::collections::{HashMap, HashSet};
|
|||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Read};
|
||||
use std::path::Path;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static SUMMARY: &str = "Topological sort the strings in FILE.
|
||||
|
@ -45,7 +46,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
file_buf = match File::open(Path::new(&input)) {
|
||||
Ok(a) => a,
|
||||
_ => {
|
||||
show_error!("{}: No such file or directory", input);
|
||||
show_error!("{}: No such file or directory", input.maybe_quote());
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
@ -68,7 +69,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
for ab in tokens.chunks(2) {
|
||||
match ab.len() {
|
||||
2 => g.add_edge(&ab[0], &ab[1]),
|
||||
_ => crash!(1, "{}: input contains an odd number of tokens", input),
|
||||
_ => crash!(
|
||||
1,
|
||||
"{}: input contains an odd number of tokens",
|
||||
input.maybe_quote()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use std::fs::File;
|
|||
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Stdout, Write};
|
||||
use std::str::from_utf8;
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static NAME: &str = "unexpand";
|
||||
|
@ -141,9 +142,9 @@ fn open(path: String) -> BufReader<Box<dyn Read + 'static>> {
|
|||
if path == "-" {
|
||||
BufReader::new(Box::new(stdin()) as Box<dyn Read>)
|
||||
} else {
|
||||
file_buf = match File::open(&path[..]) {
|
||||
file_buf = match File::open(&path) {
|
||||
Ok(a) => a,
|
||||
Err(e) => crash!(1, "{}: {}", &path[..], e),
|
||||
Err(e) => crash!(1, "{}: {}", path.maybe_quote(), e),
|
||||
};
|
||||
BufReader::new(Box::new(file_buf) as Box<dyn Read>)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Result, Write}
|
|||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use strum_macros::{AsRefStr, EnumString};
|
||||
use uucore::display::Quotable;
|
||||
|
||||
static ABOUT: &str = "Report or omit repeated lines.";
|
||||
pub mod options {
|
||||
|
@ -217,7 +218,14 @@ fn get_line_string(io_line: Result<Vec<u8>>) -> String {
|
|||
fn opt_parsed<T: FromStr>(opt_name: &str, matches: &ArgMatches) -> Option<T> {
|
||||
matches.value_of(opt_name).map(|arg_str| {
|
||||
let opt_val: Option<T> = arg_str.parse().ok();
|
||||
opt_val.unwrap_or_else(|| crash!(1, "Invalid argument for {}: {}", opt_name, arg_str))
|
||||
opt_val.unwrap_or_else(|| {
|
||||
crash!(
|
||||
1,
|
||||
"Invalid argument for {}: {}",
|
||||
opt_name,
|
||||
arg_str.maybe_quote()
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ use libc::{lstat, stat, unlink};
|
|||
use libc::{S_IFLNK, S_IFMT, S_IFREG};
|
||||
use std::ffi::CString;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static ABOUT: &str = "Unlink the file at [FILE].";
|
||||
|
@ -63,7 +64,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let result = unsafe { lstat(c_string.as_ptr(), &mut buf as *mut stat) };
|
||||
|
||||
if result < 0 {
|
||||
crash!(1, "Cannot stat '{}': {}", paths[0], Error::last_os_error());
|
||||
crash!(
|
||||
1,
|
||||
"Cannot stat {}: {}",
|
||||
paths[0].quote(),
|
||||
Error::last_os_error()
|
||||
);
|
||||
}
|
||||
|
||||
buf.st_mode & S_IFMT
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
//! Common functions to manage permissions
|
||||
|
||||
use crate::display::Quotable;
|
||||
use crate::error::strip_errno;
|
||||
use crate::error::UResult;
|
||||
use crate::error::USimpleError;
|
||||
|
@ -80,29 +81,29 @@ pub fn wrap_chown<P: AsRef<Path>>(
|
|||
VerbosityLevel::Silent => (),
|
||||
level => {
|
||||
out = format!(
|
||||
"changing {} of '{}': {}",
|
||||
"changing {} of {}: {}",
|
||||
if verbosity.groups_only {
|
||||
"group"
|
||||
} else {
|
||||
"ownership"
|
||||
},
|
||||
path.display(),
|
||||
path.quote(),
|
||||
e
|
||||
);
|
||||
if level == VerbosityLevel::Verbose {
|
||||
out = if verbosity.groups_only {
|
||||
format!(
|
||||
"{}\nfailed to change group of '{}' from {} to {}",
|
||||
"{}\nfailed to change group of {} from {} to {}",
|
||||
out,
|
||||
path.display(),
|
||||
path.quote(),
|
||||
entries::gid2grp(meta.gid()).unwrap(),
|
||||
entries::gid2grp(dest_gid).unwrap()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}\nfailed to change ownership of '{}' from {}:{} to {}:{}",
|
||||
"{}\nfailed to change ownership of {} from {}:{} to {}:{}",
|
||||
out,
|
||||
path.display(),
|
||||
path.quote(),
|
||||
entries::uid2usr(meta.uid()).unwrap(),
|
||||
entries::gid2grp(meta.gid()).unwrap(),
|
||||
entries::uid2usr(dest_uid).unwrap(),
|
||||
|
@ -120,15 +121,15 @@ pub fn wrap_chown<P: AsRef<Path>>(
|
|||
VerbosityLevel::Changes | VerbosityLevel::Verbose => {
|
||||
out = if verbosity.groups_only {
|
||||
format!(
|
||||
"changed group of '{}' from {} to {}",
|
||||
path.display(),
|
||||
"changed group of {} from {} to {}",
|
||||
path.quote(),
|
||||
entries::gid2grp(meta.gid()).unwrap(),
|
||||
entries::gid2grp(dest_gid).unwrap()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"changed ownership of '{}' from {}:{} to {}:{}",
|
||||
path.display(),
|
||||
"changed ownership of {} from {}:{} to {}:{}",
|
||||
path.quote(),
|
||||
entries::uid2usr(meta.uid()).unwrap(),
|
||||
entries::gid2grp(meta.gid()).unwrap(),
|
||||
entries::uid2usr(dest_uid).unwrap(),
|
||||
|
@ -141,14 +142,14 @@ pub fn wrap_chown<P: AsRef<Path>>(
|
|||
} else if verbosity.level == VerbosityLevel::Verbose {
|
||||
out = if verbosity.groups_only {
|
||||
format!(
|
||||
"group of '{}' retained as {}",
|
||||
path.display(),
|
||||
"group of {} retained as {}",
|
||||
path.quote(),
|
||||
entries::gid2grp(dest_gid).unwrap_or_default()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"ownership of '{}' retained as {}:{}",
|
||||
path.display(),
|
||||
"ownership of {} retained as {}:{}",
|
||||
path.quote(),
|
||||
entries::uid2usr(dest_uid).unwrap(),
|
||||
entries::gid2grp(dest_gid).unwrap()
|
||||
)
|
||||
|
@ -358,9 +359,9 @@ impl ChownExecutor {
|
|||
match self.verbosity.level {
|
||||
VerbosityLevel::Silent => (),
|
||||
_ => show_error!(
|
||||
"cannot {} '{}': {}",
|
||||
"cannot {} {}: {}",
|
||||
if follow { "dereference" } else { "access" },
|
||||
path.display(),
|
||||
path.quote(),
|
||||
strip_errno(&e)
|
||||
),
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ use std::sync::atomic::Ordering;
|
|||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::display::Quotable;
|
||||
|
||||
pub fn get_utility_is_second_arg() -> bool {
|
||||
crate::macros::UTILITY_IS_SECOND_ARG.load(Ordering::SeqCst)
|
||||
}
|
||||
|
@ -171,14 +173,15 @@ pub trait Args: Iterator<Item = OsString> + Sized {
|
|||
Ok(string) => Ok(string),
|
||||
Err(s_ret) => {
|
||||
full_conversion = false;
|
||||
let lossy_conversion = s_ret.to_string_lossy();
|
||||
eprintln!(
|
||||
"Input with broken encoding occurred! (s = '{}') ",
|
||||
&lossy_conversion
|
||||
"Input with broken encoding occurred! (s = {}) ",
|
||||
s_ret.quote()
|
||||
);
|
||||
match handling {
|
||||
InvalidEncodingHandling::Ignore => Err(String::new()),
|
||||
InvalidEncodingHandling::ConvertLossy => Err(lossy_conversion.to_string()),
|
||||
InvalidEncodingHandling::ConvertLossy => {
|
||||
Err(s_ret.to_string_lossy().into_owned())
|
||||
}
|
||||
InvalidEncodingHandling::Panic => {
|
||||
panic!("Broken encoding found but caller cannot handle it")
|
||||
}
|
||||
|
|
|
@ -78,7 +78,10 @@
|
|||
|
||||
// spell-checker:ignore backupopt
|
||||
|
||||
use crate::error::{UError, UResult};
|
||||
use crate::{
|
||||
display::Quotable,
|
||||
error::{UError, UResult},
|
||||
};
|
||||
use clap::ArgMatches;
|
||||
use std::{
|
||||
env,
|
||||
|
@ -167,18 +170,22 @@ impl Display for BackupError {
|
|||
match self {
|
||||
BE::InvalidArgument(arg, origin) => write!(
|
||||
f,
|
||||
"invalid argument '{}' for '{}'\n{}",
|
||||
arg, origin, VALID_ARGS_HELP
|
||||
"invalid argument {} for '{}'\n{}",
|
||||
arg.quote(),
|
||||
origin,
|
||||
VALID_ARGS_HELP
|
||||
),
|
||||
BE::AmbiguousArgument(arg, origin) => write!(
|
||||
f,
|
||||
"ambiguous argument '{}' for '{}'\n{}",
|
||||
arg, origin, VALID_ARGS_HELP
|
||||
"ambiguous argument {} for '{}'\n{}",
|
||||
arg.quote(),
|
||||
origin,
|
||||
VALID_ARGS_HELP
|
||||
),
|
||||
BE::BackupImpossible() => write!(f, "cannot create backup"),
|
||||
// Placeholder for later
|
||||
// BE::BackupFailed(from, to, e) => Display::fmt(
|
||||
// &uio_error!(e, "failed to backup '{}' to '{}'", from.display(), to.display()),
|
||||
// &uio_error!(e, "failed to backup {} to {}", from.quote(), to.quote()),
|
||||
// f
|
||||
// ),
|
||||
}
|
||||
|
|
|
@ -87,13 +87,16 @@ macro_rules! impl_as_ref {
|
|||
};
|
||||
}
|
||||
|
||||
impl_as_ref!(str);
|
||||
impl_as_ref!(&'_ str);
|
||||
impl_as_ref!(String);
|
||||
impl_as_ref!(std::path::Path);
|
||||
impl_as_ref!(&'_ std::path::Path);
|
||||
impl_as_ref!(std::path::PathBuf);
|
||||
impl_as_ref!(std::path::Component<'_>);
|
||||
impl_as_ref!(std::path::Components<'_>);
|
||||
impl_as_ref!(std::path::Iter<'_>);
|
||||
impl_as_ref!(std::ffi::OsStr);
|
||||
impl_as_ref!(&'_ std::ffi::OsStr);
|
||||
impl_as_ref!(std::ffi::OsString);
|
||||
|
||||
|
@ -106,6 +109,13 @@ impl Quotable for Cow<'_, str> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Quotable for Cow<'_, std::path::Path> {
|
||||
fn quote(&self) -> Quoted<'_> {
|
||||
let text: &std::path::Path = self.as_ref();
|
||||
Quoted::new(text.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around [`OsStr`] for printing paths with quoting and escaping applied.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Quoted<'a> {
|
||||
|
@ -407,6 +417,19 @@ pub fn println_verbatim<S: AsRef<OsStr>>(text: S) -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Like `println_verbatim`, without the trailing newline.
|
||||
pub fn print_verbatim<S: AsRef<OsStr>>(text: S) -> io::Result<()> {
|
||||
let mut stdout = io::stdout();
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
{
|
||||
stdout.write_all(text.as_ref().as_bytes())
|
||||
}
|
||||
#[cfg(not(any(unix, target_os = "wasi")))]
|
||||
{
|
||||
write!(stdout, "{}", std::path::Path::new(text.as_ref()).display())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -99,7 +99,10 @@ pub type UResult<T> = Result<T, Box<dyn UError>>;
|
|||
/// An example of a custom error from `ls`:
|
||||
///
|
||||
/// ```
|
||||
/// use uucore::error::{UError, UResult};
|
||||
/// use uucore::{
|
||||
/// display::Quotable,
|
||||
/// error::{UError, UResult}
|
||||
/// };
|
||||
/// use std::{
|
||||
/// error::Error,
|
||||
/// fmt::{Display, Debug},
|
||||
|
@ -126,8 +129,8 @@ pub type UResult<T> = Result<T, Box<dyn UError>>;
|
|||
/// impl Display for LsError {
|
||||
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
/// match self {
|
||||
/// LsError::InvalidLineWidth(s) => write!(f, "invalid line width: '{}'", s),
|
||||
/// LsError::NoMetadata(p) => write!(f, "could not open file: '{}'", p.display()),
|
||||
/// LsError::InvalidLineWidth(s) => write!(f, "invalid line width: {}", s.quote()),
|
||||
/// LsError::NoMetadata(p) => write!(f, "could not open file: {}", p.quote()),
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
|
@ -158,7 +161,10 @@ pub trait UError: Error + Send {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use uucore::error::{UError};
|
||||
/// use uucore::{
|
||||
/// display::Quotable,
|
||||
/// error::UError
|
||||
/// };
|
||||
/// use std::{
|
||||
/// error::Error,
|
||||
/// fmt::{Display, Debug},
|
||||
|
@ -189,8 +195,8 @@ pub trait UError: Error + Send {
|
|||
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
/// use MyError as ME;
|
||||
/// match self {
|
||||
/// ME::Foo(s) => write!(f, "Unknown Foo: '{}'", s),
|
||||
/// ME::Bar(p) => write!(f, "Couldn't find Bar: '{}'", p.display()),
|
||||
/// ME::Foo(s) => write!(f, "Unknown Foo: {}", s.quote()),
|
||||
/// ME::Bar(p) => write!(f, "Couldn't find Bar: {}", p.quote()),
|
||||
/// ME::Bing() => write!(f, "Exterminate!"),
|
||||
/// }
|
||||
/// }
|
||||
|
@ -209,7 +215,10 @@ pub trait UError: Error + Send {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use uucore::error::{UError};
|
||||
/// use uucore::{
|
||||
/// display::Quotable,
|
||||
/// error::UError
|
||||
/// };
|
||||
/// use std::{
|
||||
/// error::Error,
|
||||
/// fmt::{Display, Debug},
|
||||
|
@ -240,8 +249,8 @@ pub trait UError: Error + Send {
|
|||
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
/// use MyError as ME;
|
||||
/// match self {
|
||||
/// ME::Foo(s) => write!(f, "Unknown Foo: '{}'", s),
|
||||
/// ME::Bar(p) => write!(f, "Couldn't find Bar: '{}'", p.display()),
|
||||
/// ME::Foo(s) => write!(f, "Unknown Foo: {}", s.quote()),
|
||||
/// ME::Bar(p) => write!(f, "Couldn't find Bar: {}", p.quote()),
|
||||
/// ME::Bing() => write!(f, "Exterminate!"),
|
||||
/// }
|
||||
/// }
|
||||
|
@ -342,7 +351,10 @@ impl UError for UUsageError {
|
|||
/// There are two ways to construct this type: with [`UIoError::new`] or by calling the
|
||||
/// [`FromIo::map_err_context`] method on a [`std::io::Result`] or [`std::io::Error`].
|
||||
/// ```
|
||||
/// use uucore::error::{FromIo, UResult, UIoError, UError};
|
||||
/// use uucore::{
|
||||
/// display::Quotable,
|
||||
/// error::{FromIo, UResult, UIoError, UError}
|
||||
/// };
|
||||
/// use std::fs::File;
|
||||
/// use std::path::Path;
|
||||
/// let path = Path::new("test.txt");
|
||||
|
@ -350,12 +362,12 @@ impl UError for UUsageError {
|
|||
/// // Manual construction
|
||||
/// let e: Box<dyn UError> = UIoError::new(
|
||||
/// std::io::ErrorKind::NotFound,
|
||||
/// format!("cannot access '{}'", path.display())
|
||||
/// format!("cannot access {}", path.quote())
|
||||
/// );
|
||||
/// let res: UResult<()> = Err(e.into());
|
||||
///
|
||||
/// // Converting from an `std::io::Error`.
|
||||
/// let res: UResult<File> = File::open(path).map_err_context(|| format!("cannot access '{}'", path.display()));
|
||||
/// let res: UResult<File> = File::open(path).map_err_context(|| format!("cannot access {}", path.quote()));
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct UIoError {
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::display::Quotable;
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct Range {
|
||||
pub low: usize,
|
||||
|
@ -86,7 +88,7 @@ impl Range {
|
|||
|
||||
for item in list.split(',') {
|
||||
let range_item = FromStr::from_str(item)
|
||||
.map_err(|e| format!("range '{}' was invalid: {}", item, e))?;
|
||||
.map_err(|e| format!("range {} was invalid: {}", item.quote(), e))?;
|
||||
ranges.push(range_item);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ use std::convert::TryFrom;
|
|||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
use crate::display::Quotable;
|
||||
|
||||
/// Parse a size string into a number of bytes.
|
||||
///
|
||||
/// A size string comprises an integer and an optional unit. The unit
|
||||
|
@ -107,6 +109,9 @@ impl fmt::Display for ParseSizeError {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: It's more idiomatic to move the formatting into the Display impl,
|
||||
// but there's a lot of downstream code that constructs these errors manually
|
||||
// that would be affected
|
||||
impl ParseSizeError {
|
||||
fn parse_failure(s: &str) -> ParseSizeError {
|
||||
// stderr on linux (GNU coreutils 8.32) (LC_ALL=C)
|
||||
|
@ -140,7 +145,7 @@ impl ParseSizeError {
|
|||
// --width
|
||||
// --strings
|
||||
// etc.
|
||||
ParseSizeError::ParseFailure(format!("'{}'", s))
|
||||
ParseSizeError::ParseFailure(format!("{}", s.quote()))
|
||||
}
|
||||
|
||||
fn size_too_big(s: &str) -> ParseSizeError {
|
||||
|
@ -160,7 +165,10 @@ impl ParseSizeError {
|
|||
// stderr on macos (brew - GNU coreutils 8.32) also differs for the same version, e.g.:
|
||||
// ghead: invalid number of bytes: '1Y': Value too large to be stored in data type
|
||||
// gtail: invalid number of bytes: '1Y': Value too large to be stored in data type
|
||||
ParseSizeError::SizeTooBig(format!("'{}': Value too large for defined data type", s))
|
||||
ParseSizeError::SizeTooBig(format!(
|
||||
"{}: Value too large for defined data type",
|
||||
s.quote()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +270,7 @@ mod tests {
|
|||
for &test_string in &test_strings {
|
||||
assert_eq!(
|
||||
parse_size(test_string).unwrap_err(),
|
||||
ParseSizeError::ParseFailure(format!("'{}'", test_string))
|
||||
ParseSizeError::ParseFailure(format!("{}", test_string.quote()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::display::Quotable;
|
||||
|
||||
pub fn from_str(string: &str) -> Result<Duration, String> {
|
||||
let len = string.len();
|
||||
if len == 0 {
|
||||
|
@ -25,13 +27,13 @@ pub fn from_str(string: &str) -> Result<Duration, String> {
|
|||
if string == "inf" || string == "infinity" {
|
||||
("inf", 1)
|
||||
} else {
|
||||
return Err(format!("invalid time interval '{}'", string));
|
||||
return Err(format!("invalid time interval {}", string.quote()));
|
||||
}
|
||||
}
|
||||
};
|
||||
let num = numstr
|
||||
.parse::<f64>()
|
||||
.map_err(|e| format!("invalid time interval '{}': {}", string, e))?;
|
||||
.map_err(|e| format!("invalid time interval {}: {}", string.quote(), e))?;
|
||||
|
||||
const NANOS_PER_SEC: u32 = 1_000_000_000;
|
||||
let whole_secs = num.trunc();
|
||||
|
|
|
@ -23,7 +23,7 @@ fn test_enter_chroot_fails() {
|
|||
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("chroot: cannot chroot to jail: Operation not permitted (os error 1)"));
|
||||
.starts_with("chroot: cannot chroot to 'jail': Operation not permitted (os error 1)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -34,7 +34,7 @@ fn test_no_such_directory() {
|
|||
|
||||
ucmd.arg("a")
|
||||
.fails()
|
||||
.stderr_is("chroot: cannot change root directory to `a`: no such directory");
|
||||
.stderr_is("chroot: cannot change root directory to 'a': no such directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -68,7 +68,7 @@ fn test_invalid_file() {
|
|||
.arg(folder_name)
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr_contains("cksum: 'asdf' No such file or directory");
|
||||
.stderr_contains("cksum: asdf: No such file or directory");
|
||||
|
||||
// Then check when the file is of an invalid type
|
||||
at.mkdir(folder_name);
|
||||
|
@ -76,7 +76,7 @@ fn test_invalid_file() {
|
|||
.arg(folder_name)
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr_contains("cksum: 'asdf' Is a directory");
|
||||
.stderr_contains("cksum: asdf: Is a directory");
|
||||
}
|
||||
|
||||
// Make sure crc is correct for files larger than 32 bytes
|
||||
|
|
|
@ -531,7 +531,7 @@ fn test_keys_invalid_field() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "1."])
|
||||
.fails()
|
||||
.stderr_only("sort: failed to parse key `1.`: failed to parse character index ``: cannot parse integer from empty string");
|
||||
.stderr_only("sort: failed to parse key '1.': failed to parse character index ``: cannot parse integer from empty string");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -539,7 +539,7 @@ fn test_keys_invalid_field_option() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "1.1x"])
|
||||
.fails()
|
||||
.stderr_only("sort: failed to parse key `1.1x`: invalid option: `x`");
|
||||
.stderr_only("sort: failed to parse key '1.1x': invalid option: `x`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -547,7 +547,7 @@ fn test_keys_invalid_field_zero() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "0.1"])
|
||||
.fails()
|
||||
.stderr_only("sort: failed to parse key `0.1`: field index can not be 0");
|
||||
.stderr_only("sort: failed to parse key '0.1': field index can not be 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -555,7 +555,7 @@ fn test_keys_invalid_char_zero() {
|
|||
new_ucmd!()
|
||||
.args(&["-k", "1.0"])
|
||||
.fails()
|
||||
.stderr_only("sort: failed to parse key `1.0`: invalid character index 0 for the start position of a field");
|
||||
.stderr_only("sort: failed to parse key '1.0': invalid character index 0 for the start position of a field");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -59,7 +59,7 @@ fn test_invalid_file() {
|
|||
|
||||
at.mkdir("a");
|
||||
|
||||
ucmd.arg("a").fails().stderr_is("sum: 'a' Is a directory");
|
||||
ucmd.arg("a").fails().stderr_is("sum: a: Is a directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -68,5 +68,5 @@ fn test_invalid_metadata() {
|
|||
|
||||
ucmd.arg("b")
|
||||
.fails()
|
||||
.stderr_is("sum: 'b' No such file or directory");
|
||||
.stderr_is("sum: b: No such file or directory");
|
||||
}
|
||||
|
|
|
@ -320,7 +320,7 @@ fn test_invalid_utf8_integer_compare() {
|
|||
|
||||
cmd.run()
|
||||
.status_code(2)
|
||||
.stderr_is("test: invalid integer 'fo<66>o'");
|
||||
.stderr_is("test: invalid integer $'fo\\x80o'");
|
||||
|
||||
let mut cmd = new_ucmd!();
|
||||
cmd.raw.arg(arg);
|
||||
|
@ -328,7 +328,7 @@ fn test_invalid_utf8_integer_compare() {
|
|||
|
||||
cmd.run()
|
||||
.status_code(2)
|
||||
.stderr_is("test: invalid integer 'fo<66>o'");
|
||||
.stderr_is("test: invalid integer $'fo\\x80o'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue