Skip to content

Commit 84f95d6

Browse files
author
Gunter Schmidt
committed
Feat: sdiff initial version
1 parent f83793b commit 84f95d6

9 files changed

Lines changed: 808 additions & 21 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ path = "src/main.rs"
1616

1717
[dependencies]
1818
chrono = "0.4.38"
19+
const_format = "0.2.35"
1920
diff = "0.1.13"
2021
itoa = "1.0.11"
2122
regex = "1.10.4"

src/arg_parser.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![allow(unused)]
21
// This file is part of the uutils diffutils package.
32
//
43
// For the full copyright and license information, please view the LICENSE-*
@@ -67,12 +66,19 @@ pub fn add_copyright(text: &str) -> String {
6766

6867
/// Writes the error message and adds the help hint "Try 'diff \--help' for more information."
6968
///
69+
/// * exe: [Executable]
70+
/// * msg: The message to output. It will be preceded by 'executable: '.
71+
/// Sometimes the executable is not available during error message creation,
72+
/// so #EXE will be replaced by the name of the executable, e.g. 'diff'.
73+
///
7074
/// This is the central output function. I affects all utils. \
7175
/// It allows to just use 'eprintln!("{e}");' in case of an error.
7276
pub fn format_error_text<T: Error>(executable: &Executable, error: &T) -> String {
7377
// for messages the have the executable already
7478
let exe = format!("{executable}: ");
75-
let msg = error.to_string();
79+
let msg = error
80+
.to_string()
81+
.replace("#EXE", executable.to_string().as_str());
7682
if msg.starts_with(&exe) {
7783
format!("{msg}\n{exe}Try '{executable} --help' for more information.",)
7884
} else {
@@ -565,7 +571,9 @@ pub enum ParseError {
565571

566572
/// number for an option argument incorrect
567573
InvalidValueNumber(ParsedOption),
574+
#[allow(unused)] // Allow external usage (cmp)
568575
InvalidValueNumberUnit(ParsedOption),
576+
#[allow(unused)] // Allow external usage (cmp)
569577
InvalidValueNumberOverflow(ParsedOption),
570578

571579
/// 'executable' as first parameter missing.
@@ -582,6 +590,7 @@ pub enum ParseError {
582590
NoUnicode(OsString),
583591

584592
/// Two options cannot be used together, e.g. cmp --silent and --verbose (output).
593+
#[allow(unused)] // Allow external usage (cmp)
585594
OptionsIncompatible(&'static AppOption, &'static AppOption),
586595

587596
/// Non-existent long option. This is "unrecognized" because the name can be abbreviated.
@@ -683,8 +692,10 @@ impl Display for ParseError {
683692
}
684693
}
685694

695+
#[allow(unused)] // required for cmp
686696
pub struct NumberParser {}
687697

698+
#[allow(unused)] // required for cmp
688699
impl NumberParser {
689700
/// Parses a number with an optional unit, e.g. 10MiB.
690701
///
@@ -704,10 +715,7 @@ impl NumberParser {
704715
if pos == 0 {
705716
return Err(ParseError::InvalidValueNumber(parsed_option.clone()));
706717
}
707-
multiplier = match Self::parse_number_unit(&num_unit[pos..]) {
708-
Some(m) => m,
709-
None => return Err(ParseError::InvalidValueNumberUnit(parsed_option.clone())),
710-
};
718+
multiplier = Self::parse_number_unit(&num_unit[pos..], parsed_option)?;
711719
&num_unit[0..pos]
712720
}
713721
None => {
@@ -748,8 +756,7 @@ impl NumberParser {
748756
/// Units up eo Exabyte (EiB) following GNU documentation: \
749757
/// <https://www.gnu.org/software/diffutils/manual/html_node/cmp-Options.html>.
750758
#[cfg(not(feature = "feat_allow_case_insensitive_number_units"))]
751-
// #[allow(unused)] // required for cmp
752-
pub fn parse_number_unit(unit: &str) -> Option<u64> {
759+
fn parse_number_unit(unit: &str, parsed_option: &ParsedOption) -> Result<u64, ParseError> {
753760
let multiplier = match unit {
754761
"kB" | "KB" => 1_000,
755762
"k" | "K" | "KiB" | "kiB" => 1_024,
@@ -772,19 +779,18 @@ impl NumberParser {
772779
// "YB" => 1_000_000_000_000_000_000_000_000,
773780
// "Y" | "YiB" => 1_208_925_819_614_629_174_706_176,
774781
_ => {
775-
return None;
782+
return Err(ParseError::InvalidValueNumberUnit(parsed_option.clone()));
776783
}
777784
};
778785

779-
Some(multiplier)
786+
Ok(multiplier)
780787
}
781788

782789
/// Returns a multiplier depending on the given unit, e.g. 'KiB' -> 1024,
783790
/// which then can be used to calculate the final number of bytes.
784791
/// Following GNU documentation: https://www.gnu.org/software/diffutils/manual/html_node/cmp-Options.html
785-
/// TODO case
786792
#[cfg(feature = "feat_allow_case_insensitive_number_units")]
787-
pub fn parse_number_unit(unit: &str) -> Option<u64> {
793+
fn parse_number_unit(unit: &str, parsed_option: &ParsedOption) -> Result<u64, ParseError> {
788794
// Note that GNU cmp advertises supporting up to Y, but fails if you try
789795
// to actually use anything beyond E.
790796
let unit = unit.to_owned().to_ascii_lowercase();
@@ -811,11 +817,11 @@ impl NumberParser {
811817
// "yb" => 1_000_000_000_000_000_000_000_000,
812818
// "y" | "yib" => 1_208_925_819_614_629_174_706_176,
813819
_ => {
814-
return None;
820+
return Err(ParseError::InvalidValueNumberUnit(parsed_option.clone()));
815821
}
816822
};
817823

818-
Some(multiplier)
824+
Ok(multiplier)
819825
}
820826
}
821827

src/diff.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn main(opts: Peekable<ArgsOs>) -> ExitCode {
8181
}),
8282
Format::SideBySide => {
8383
let mut output = stdout().lock();
84-
side_diff::diff(&from_content, &to_content, &mut output, &params)
84+
side_diff::diff(&from_content, &to_content, &mut output, &(&params).into())
8585
}
8686
};
8787
if params.brief && !result.is_empty() {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod ed_diff;
55
pub mod macros;
66
pub mod normal_diff;
77
pub mod params;
8+
pub mod sdiff;
89
pub mod side_diff;
910
pub mod unified_diff;
1011
pub mod utils;

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod ed_diff;
1919
mod macros;
2020
mod normal_diff;
2121
mod params;
22+
mod sdiff;
2223
mod side_diff;
2324
mod unified_diff;
2425
mod utils;
@@ -73,6 +74,7 @@ fn main() -> ExitCode {
7374
match util_name.to_str() {
7475
Some("diff") => diff::main(args),
7576
Some("cmp") => cmp::main(args),
77+
Some("sdiff") => sdiff::main(args),
7678
Some(name) => {
7779
eprintln!("{name}: utility not supported");
7880
ExitCode::from(2)

0 commit comments

Comments
 (0)