mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
commit
72bdee0111
6 changed files with 41 additions and 99 deletions
|
@ -16,7 +16,7 @@ use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{FromIo, UResult};
|
use uucore::error::{FromIo, UResult};
|
||||||
use uucore::{crash_if_err, format_usage, help_about, help_section, help_usage};
|
use uucore::{format_usage, help_about, help_section, help_usage};
|
||||||
|
|
||||||
mod csplit_error;
|
mod csplit_error;
|
||||||
mod patterns;
|
mod patterns;
|
||||||
|
@ -51,26 +51,23 @@ pub struct CsplitOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CsplitOptions {
|
impl CsplitOptions {
|
||||||
fn new(matches: &ArgMatches) -> Self {
|
fn new(matches: &ArgMatches) -> Result<Self, CsplitError> {
|
||||||
let keep_files = matches.get_flag(options::KEEP_FILES);
|
let keep_files = matches.get_flag(options::KEEP_FILES);
|
||||||
let quiet = matches.get_flag(options::QUIET);
|
let quiet = matches.get_flag(options::QUIET);
|
||||||
let elide_empty_files = matches.get_flag(options::ELIDE_EMPTY_FILES);
|
let elide_empty_files = matches.get_flag(options::ELIDE_EMPTY_FILES);
|
||||||
let suppress_matched = matches.get_flag(options::SUPPRESS_MATCHED);
|
let suppress_matched = matches.get_flag(options::SUPPRESS_MATCHED);
|
||||||
|
|
||||||
Self {
|
Ok(Self {
|
||||||
split_name: crash_if_err!(
|
split_name: SplitName::new(
|
||||||
1,
|
|
||||||
SplitName::new(
|
|
||||||
matches.get_one::<String>(options::PREFIX).cloned(),
|
matches.get_one::<String>(options::PREFIX).cloned(),
|
||||||
matches.get_one::<String>(options::SUFFIX_FORMAT).cloned(),
|
matches.get_one::<String>(options::SUFFIX_FORMAT).cloned(),
|
||||||
matches.get_one::<String>(options::DIGITS).cloned()
|
matches.get_one::<String>(options::DIGITS).cloned(),
|
||||||
)
|
)?,
|
||||||
),
|
|
||||||
keep_files,
|
keep_files,
|
||||||
quiet,
|
quiet,
|
||||||
elide_empty_files,
|
elide_empty_files,
|
||||||
suppress_matched,
|
suppress_matched,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,7 +558,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
let options = CsplitOptions::new(&matches);
|
let options = CsplitOptions::new(&matches)?;
|
||||||
if file_name == "-" {
|
if file_name == "-" {
|
||||||
let stdin = io::stdin();
|
let stdin = io::stdin();
|
||||||
Ok(csplit(&options, &patterns, stdin.lock())?)
|
Ok(csplit(&options, &patterns, stdin.lock())?)
|
||||||
|
|
|
@ -20,7 +20,7 @@ use std::os::unix::ffi::OsStrExt;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError};
|
use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError};
|
||||||
use uucore::line_ending::LineEnding;
|
use uucore::line_ending::LineEnding;
|
||||||
use uucore::{crash_if_err, format_usage, help_about, help_usage};
|
use uucore::{format_usage, help_about, help_usage};
|
||||||
|
|
||||||
const ABOUT: &str = help_about!("join.md");
|
const ABOUT: &str = help_about!("join.md");
|
||||||
const USAGE: &str = help_usage!("join.md");
|
const USAGE: &str = help_usage!("join.md");
|
||||||
|
@ -587,15 +587,19 @@ impl<'a> State<'a> {
|
||||||
!self.seq.is_empty()
|
!self.seq.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize<Sep: Separator>(&mut self, read_sep: &Sep, autoformat: bool) -> usize {
|
fn initialize<Sep: Separator>(
|
||||||
if let Some(line) = crash_if_err!(1, self.read_line(read_sep)) {
|
&mut self,
|
||||||
|
read_sep: &Sep,
|
||||||
|
autoformat: bool,
|
||||||
|
) -> std::io::Result<usize> {
|
||||||
|
if let Some(line) = self.read_line(read_sep)? {
|
||||||
self.seq.push(line);
|
self.seq.push(line);
|
||||||
|
|
||||||
if autoformat {
|
if autoformat {
|
||||||
return self.seq[0].field_ranges.len();
|
return Ok(self.seq[0].field_ranges.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize<Sep: Separator>(
|
fn finalize<Sep: Separator>(
|
||||||
|
@ -1008,20 +1012,21 @@ fn exec<Sep: Separator>(file1: &str, file2: &str, settings: Settings, sep: Sep)
|
||||||
|
|
||||||
let format = if settings.autoformat {
|
let format = if settings.autoformat {
|
||||||
let mut format = vec![Spec::Key];
|
let mut format = vec![Spec::Key];
|
||||||
let mut initialize = |state: &mut State| {
|
let mut initialize = |state: &mut State| -> UResult<()> {
|
||||||
let max_fields = state.initialize(&sep, settings.autoformat);
|
let max_fields = state.initialize(&sep, settings.autoformat)?;
|
||||||
for i in 0..max_fields {
|
for i in 0..max_fields {
|
||||||
if i != state.key {
|
if i != state.key {
|
||||||
format.push(Spec::Field(state.file_num, i));
|
format.push(Spec::Field(state.file_num, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
};
|
};
|
||||||
initialize(&mut state1);
|
initialize(&mut state1)?;
|
||||||
initialize(&mut state2);
|
initialize(&mut state2)?;
|
||||||
format
|
format
|
||||||
} else {
|
} else {
|
||||||
state1.initialize(&sep, settings.autoformat);
|
state1.initialize(&sep, settings.autoformat)?;
|
||||||
state2.initialize(&sep, settings.autoformat);
|
state2.initialize(&sep, settings.autoformat)?;
|
||||||
settings.format
|
settings.format
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use std::str::from_utf8;
|
||||||
use unicode_width::UnicodeWidthChar;
|
use unicode_width::UnicodeWidthChar;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
||||||
use uucore::{crash_if_err, format_usage, help_about, help_usage, show};
|
use uucore::{format_usage, help_about, help_usage, show};
|
||||||
|
|
||||||
const USAGE: &str = help_usage!("unexpand.md");
|
const USAGE: &str = help_usage!("unexpand.md");
|
||||||
const ABOUT: &str = help_about!("unexpand.md");
|
const ABOUT: &str = help_about!("unexpand.md");
|
||||||
|
@ -244,7 +244,7 @@ fn write_tabs(
|
||||||
prevtab: bool,
|
prevtab: bool,
|
||||||
init: bool,
|
init: bool,
|
||||||
amode: bool,
|
amode: bool,
|
||||||
) {
|
) -> UResult<()> {
|
||||||
// This conditional establishes the following:
|
// This conditional establishes the following:
|
||||||
// We never turn a single space before a non-blank into
|
// We never turn a single space before a non-blank into
|
||||||
// a tab, unless it's at the start of the line.
|
// a tab, unless it's at the start of the line.
|
||||||
|
@ -255,15 +255,16 @@ fn write_tabs(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
crash_if_err!(1, output.write_all(b"\t"));
|
output.write_all(b"\t")?;
|
||||||
scol += nts;
|
scol += nts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while col > scol {
|
while col > scol {
|
||||||
crash_if_err!(1, output.write_all(b" "));
|
output.write_all(b" ")?;
|
||||||
scol += 1;
|
scol += 1;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
|
@ -325,7 +326,7 @@ fn unexpand_line(
|
||||||
options: &Options,
|
options: &Options,
|
||||||
lastcol: usize,
|
lastcol: usize,
|
||||||
ts: &[usize],
|
ts: &[usize],
|
||||||
) -> std::io::Result<()> {
|
) -> UResult<()> {
|
||||||
let mut byte = 0; // offset into the buffer
|
let mut byte = 0; // offset into the buffer
|
||||||
let mut col = 0; // the current column
|
let mut col = 0; // the current column
|
||||||
let mut scol = 0; // the start col for the current span, i.e., the already-printed width
|
let mut scol = 0; // the start col for the current span, i.e., the already-printed width
|
||||||
|
@ -335,7 +336,7 @@ fn unexpand_line(
|
||||||
while byte < buf.len() {
|
while byte < buf.len() {
|
||||||
// when we have a finite number of columns, never convert past the last column
|
// when we have a finite number of columns, never convert past the last column
|
||||||
if lastcol > 0 && col >= lastcol {
|
if lastcol > 0 && col >= lastcol {
|
||||||
write_tabs(output, ts, scol, col, pctype == CharType::Tab, init, true);
|
write_tabs(output, ts, scol, col, pctype == CharType::Tab, init, true)?;
|
||||||
output.write_all(&buf[byte..])?;
|
output.write_all(&buf[byte..])?;
|
||||||
scol = col;
|
scol = col;
|
||||||
break;
|
break;
|
||||||
|
@ -370,7 +371,7 @@ fn unexpand_line(
|
||||||
pctype == CharType::Tab,
|
pctype == CharType::Tab,
|
||||||
init,
|
init,
|
||||||
options.aflag,
|
options.aflag,
|
||||||
);
|
)?;
|
||||||
init = false; // no longer at the start of a line
|
init = false; // no longer at the start of a line
|
||||||
col = if ctype == CharType::Other {
|
col = if ctype == CharType::Other {
|
||||||
// use computed width
|
// use computed width
|
||||||
|
@ -391,7 +392,7 @@ fn unexpand_line(
|
||||||
}
|
}
|
||||||
|
|
||||||
// write out anything remaining
|
// write out anything remaining
|
||||||
write_tabs(output, ts, scol, col, pctype == CharType::Tab, init, true);
|
write_tabs(output, ts, scol, col, pctype == CharType::Tab, init, true)?;
|
||||||
output.flush()?;
|
output.flush()?;
|
||||||
buf.truncate(0); // clear out the buffer
|
buf.truncate(0); // clear out the buffer
|
||||||
|
|
||||||
|
|
|
@ -587,7 +587,7 @@ impl FsUsage {
|
||||||
let mut number_of_free_clusters = 0;
|
let mut number_of_free_clusters = 0;
|
||||||
let mut total_number_of_clusters = 0;
|
let mut total_number_of_clusters = 0;
|
||||||
|
|
||||||
let success = unsafe {
|
unsafe {
|
||||||
let path = to_nul_terminated_wide_string(path);
|
let path = to_nul_terminated_wide_string(path);
|
||||||
GetDiskFreeSpaceW(
|
GetDiskFreeSpaceW(
|
||||||
path.as_ptr(),
|
path.as_ptr(),
|
||||||
|
@ -595,15 +595,7 @@ impl FsUsage {
|
||||||
&mut bytes_per_sector,
|
&mut bytes_per_sector,
|
||||||
&mut number_of_free_clusters,
|
&mut number_of_free_clusters,
|
||||||
&mut total_number_of_clusters,
|
&mut total_number_of_clusters,
|
||||||
)
|
);
|
||||||
};
|
|
||||||
if 0 == success {
|
|
||||||
// Fails in case of CD for example
|
|
||||||
// crash!(
|
|
||||||
// EXIT_ERR,
|
|
||||||
// "GetDiskFreeSpaceW failed: {}",
|
|
||||||
// IOError::last_os_error()
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes_per_cluster = sectors_per_cluster as u64 * bytes_per_sector as u64;
|
let bytes_per_cluster = sectors_per_cluster as u64 * bytes_per_sector as u64;
|
||||||
|
|
|
@ -380,7 +380,10 @@ macro_rules! prompt_yes(
|
||||||
eprint!("{}: ", uucore::util_name());
|
eprint!("{}: ", uucore::util_name());
|
||||||
eprint!($($args)+);
|
eprint!($($args)+);
|
||||||
eprint!(" ");
|
eprint!(" ");
|
||||||
uucore::crash_if_err!(1, std::io::stderr().flush());
|
let res = std::io::stderr().flush().map_err(|err| {
|
||||||
|
$crate::error::USimpleError::new(1, err.to_string())
|
||||||
|
});
|
||||||
|
uucore::show_if_err!(res);
|
||||||
uucore::read_yes()
|
uucore::read_yes()
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
//! [`crate::show_if_err!`]
|
//! [`crate::show_if_err!`]
|
||||||
//! - From custom messages: [`crate::show_error!`]
|
//! - From custom messages: [`crate::show_error!`]
|
||||||
//! - Print warnings: [`crate::show_warning!`]
|
//! - Print warnings: [`crate::show_warning!`]
|
||||||
//! - Terminate util execution
|
|
||||||
//! - Crash program: [`crate::crash!`], [`crate::crash_if_err!`]
|
|
||||||
|
|
||||||
// spell-checker:ignore sourcepath targetpath rustdoc
|
// spell-checker:ignore sourcepath targetpath rustdoc
|
||||||
|
|
||||||
|
@ -189,57 +187,3 @@ macro_rules! show_warning_caps(
|
||||||
eprintln!($($args)+);
|
eprintln!($($args)+);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Display an error and [`std::process::exit`]
|
|
||||||
///
|
|
||||||
/// Displays the provided error message using [`show_error!`], then invokes
|
|
||||||
/// [`std::process::exit`] with the provided exit code.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// # #[macro_use]
|
|
||||||
/// # extern crate uucore;
|
|
||||||
/// # fn main() {
|
|
||||||
/// // outputs <name>: Couldn't apply foo to bar
|
|
||||||
/// // and terminates execution
|
|
||||||
/// crash!(1, "Couldn't apply {} to {}", "foo", "bar");
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! crash(
|
|
||||||
($exit_code:expr, $($args:tt)+) => ({
|
|
||||||
$crate::show_error!($($args)+);
|
|
||||||
std::process::exit($exit_code);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Unwrap a [`std::result::Result`], crashing instead of panicking.
|
|
||||||
///
|
|
||||||
/// If the result is an `Ok`-variant, returns the value contained inside. If it
|
|
||||||
/// is an `Err`-variant, invokes [`crash!`] with the formatted error instead.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// # #[macro_use]
|
|
||||||
/// # extern crate uucore;
|
|
||||||
/// # fn main() {
|
|
||||||
/// let is_ok: Result<u32, &str> = Ok(1);
|
|
||||||
/// // Does nothing
|
|
||||||
/// crash_if_err!(1, is_ok);
|
|
||||||
///
|
|
||||||
/// let is_err: Result<u32, &str> = Err("This didn't work...");
|
|
||||||
/// // Calls `crash!`
|
|
||||||
/// crash_if_err!(1, is_err);
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! crash_if_err(
|
|
||||||
($exit_code:expr, $exp:expr) => (
|
|
||||||
match $exp {
|
|
||||||
Ok(m) => m,
|
|
||||||
Err(f) => $crate::crash!($exit_code, "{}", f),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue