From d4e2b18952e24fc7403d0910f3ec559dac1e82a8 Mon Sep 17 00:00:00 2001 From: sylvestre Date: Wed, 19 Apr 2023 02:38:36 +0000 Subject: [PATCH] deploy: f0e8d44e6e64ee3354f95864c0a25b74cf1c1151 --- dev/src/uu_fmt/fmt.rs.html | 142 ++++++--- dev/src/uu_hashsum/hashsum.rs.html | 416 +++++++++++++++++---------- dev/src/uu_install/install.rs.html | 306 +++++++++++++++----- dev/src/uu_stat/stat.rs.html | 320 +++++++++++++++++---- dev/uu_fmt/fn.uu_app.html | 2 +- dev/uu_fmt/fn.uumain.html | 2 +- dev/uu_fmt/index.html | 2 +- dev/uu_hashsum/fn.uu_app_b3sum.html | 2 +- dev/uu_hashsum/fn.uu_app_bits.html | 2 +- dev/uu_hashsum/fn.uu_app_common.html | 2 +- dev/uu_hashsum/fn.uu_app_custom.html | 2 +- dev/uu_hashsum/fn.uu_app_length.html | 2 +- dev/uu_hashsum/fn.uumain.html | 2 +- dev/uu_hashsum/index.html | 2 +- dev/uu_install/index.html | 2 +- dev/uu_stat/fn.uu_app.html | 2 +- dev/uu_stat/fn.uumain.html | 2 +- dev/uu_stat/index.html | 2 +- 18 files changed, 873 insertions(+), 339 deletions(-) diff --git a/dev/src/uu_fmt/fmt.rs.html b/dev/src/uu_fmt/fmt.rs.html index fb6dabcb0..2e89b1a52 100644 --- a/dev/src/uu_fmt/fmt.rs.html +++ b/dev/src/uu_fmt/fmt.rs.html @@ -357,6 +357,41 @@ 357 358 359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394
//  * This file is part of `fmt` from the uutils coreutils package.
 //  *
 //  * (c) kwantam <kwantam@gmail.com>
@@ -370,7 +405,7 @@
 use std::cmp;
 use std::fs::File;
 use std::io::{stdin, stdout, Write};
-use std::io::{BufReader, BufWriter, Read};
+use std::io::{BufReader, BufWriter, Read, Stdout};
 use uucore::display::Quotable;
 use uucore::error::{FromIo, UResult, USimpleError};
 use uucore::{format_usage, help_about, help_usage, show_warning};
@@ -419,10 +454,16 @@
     goal: usize,
     tabwidth: usize,
 }
-
-#[uucore::main]
-#[allow(clippy::cognitive_complexity)]
-pub fn uumain(args: impl uucore::Args) -> UResult<()> {
+/// Parse the command line arguments and return the list of files and formatting options.
+///
+/// # Arguments
+///
+/// * `args` - Command line arguments.
+///
+/// # Returns
+///
+/// A tuple containing a vector of file names and a `FmtOptions` struct.
+fn parse_arguments(args: impl uucore::Args) -> UResult<(Vec<String>, FmtOptions)> {
     let matches = uu_app().try_get_matches_from(args)?;
 
     let mut files: Vec<String> = matches
@@ -536,39 +577,68 @@
         files.push("-".to_owned());
     }
 
+    Ok((files, fmt_opts))
+}
+
+/// Process the content of a file and format it according to the provided options.
+///
+/// # Arguments
+///
+/// * `file_name` - The name of the file to process. A value of "-" represents the standard input.
+/// * `fmt_opts` - A reference to a `FmtOptions` struct containing the formatting options.
+/// * `ostream` - A mutable reference to a `BufWriter` wrapping the standard output.
+///
+/// # Returns
+///
+/// A `UResult<()>` indicating success or failure.
+fn process_file(
+    file_name: &str,
+    fmt_opts: &FmtOptions,
+    ostream: &mut BufWriter<Stdout>,
+) -> UResult<()> {
+    let mut fp = match file_name {
+        "-" => BufReader::new(Box::new(stdin()) as Box<dyn Read + 'static>),
+        _ => match File::open(file_name) {
+            Ok(f) => BufReader::new(Box::new(f) as Box<dyn Read + 'static>),
+            Err(e) => {
+                show_warning!("{}: {}", file_name.maybe_quote(), e);
+                return Ok(());
+            }
+        },
+    };
+
+    let p_stream = ParagraphStream::new(fmt_opts, &mut fp);
+    for para_result in p_stream {
+        match para_result {
+            Err(s) => {
+                ostream
+                    .write_all(s.as_bytes())
+                    .map_err_context(|| "failed to write output".to_string())?;
+                ostream
+                    .write_all(b"\n")
+                    .map_err_context(|| "failed to write output".to_string())?;
+            }
+            Ok(para) => break_lines(&para, fmt_opts, ostream)
+                .map_err_context(|| "failed to write output".to_string())?,
+        }
+    }
+
+    // flush the output after each file
+    ostream
+        .flush()
+        .map_err_context(|| "failed to write output".to_string())?;
+
+    Ok(())
+}
+
+#[uucore::main]
+pub fn uumain(args: impl uucore::Args) -> UResult<()> {
+    let (files, fmt_opts) = parse_arguments(args)?;
+
     let mut ostream = BufWriter::new(stdout());
 
-    for i in files.iter().map(|x| &x[..]) {
-        let mut fp = match i {
-            "-" => BufReader::new(Box::new(stdin()) as Box<dyn Read + 'static>),
-            _ => match File::open(i) {
-                Ok(f) => BufReader::new(Box::new(f) as Box<dyn Read + 'static>),
-                Err(e) => {
-                    show_warning!("{}: {}", i.maybe_quote(), e);
-                    continue;
-                }
-            },
-        };
-        let p_stream = ParagraphStream::new(&fmt_opts, &mut fp);
-        for para_result in p_stream {
-            match para_result {
-                Err(s) => {
-                    ostream
-                        .write_all(s.as_bytes())
-                        .map_err_context(|| "failed to write output".to_string())?;
-                    ostream
-                        .write_all(b"\n")
-                        .map_err_context(|| "failed to write output".to_string())?;
-                }
-                Ok(para) => break_lines(&para, &fmt_opts, &mut ostream)
-                    .map_err_context(|| "failed to write output".to_string())?,
-            }
-        }
-
-        // flush the output after each file
-        ostream
-            .flush()
-            .map_err_context(|| "failed to write output".to_string())?;
+    for file_name in &files {
+        process_file(file_name, &fmt_opts, &mut ostream)?;
     }
 
     Ok(())
diff --git a/dev/src/uu_hashsum/hashsum.rs.html b/dev/src/uu_hashsum/hashsum.rs.html
index b8e7a5f0f..cfa794d39 100644
--- a/dev/src/uu_hashsum/hashsum.rs.html
+++ b/dev/src/uu_hashsum/hashsum.rs.html
@@ -721,6 +721,55 @@
 721
 722
 723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
 
//  * This file is part of the uutils coreutils package.
 //  *
 //  * (c) Alex Lyon <arcterus@mail.com>
@@ -773,71 +822,140 @@
     zero: bool,
 }
 
-#[allow(clippy::cognitive_complexity)]
+/// Creates a Blake2b hasher instance based on the specified length argument.
+///
+/// # Returns
+///
+/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
+///
+/// # Panics
+///
+/// Panics if the length is not a multiple of 8 or if it is greater than 512.
+fn create_blake2b(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
+    match matches.get_one::<usize>("length") {
+        Some(0) | None => ("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512),
+        Some(length_in_bits) => {
+            if *length_in_bits > 512 {
+                crash!(1, "Invalid length (maximum digest length is 512 bits)")
+            }
+
+            if length_in_bits % 8 == 0 {
+                let length_in_bytes = length_in_bits / 8;
+                (
+                    "BLAKE2",
+                    Box::new(Blake2b::with_output_bytes(length_in_bytes)),
+                    *length_in_bits,
+                )
+            } else {
+                crash!(1, "Invalid length (expected a multiple of 8)")
+            }
+        }
+    }
+}
+
+/// Creates a SHA3 hasher instance based on the specified bits argument.
+///
+/// # Returns
+///
+/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
+///
+/// # Panics
+///
+/// Panics if an unsupported output size is provided, or if the `--bits` flag is missing.
+fn create_sha3(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
+    match matches.get_one::<usize>("bits") {
+        Some(224) => (
+            "SHA3-224",
+            Box::new(Sha3_224::new()) as Box<dyn Digest>,
+            224,
+        ),
+        Some(256) => (
+            "SHA3-256",
+            Box::new(Sha3_256::new()) as Box<dyn Digest>,
+            256,
+        ),
+        Some(384) => (
+            "SHA3-384",
+            Box::new(Sha3_384::new()) as Box<dyn Digest>,
+            384,
+        ),
+        Some(512) => (
+            "SHA3-512",
+            Box::new(Sha3_512::new()) as Box<dyn Digest>,
+            512,
+        ),
+        Some(_) => crash!(
+            1,
+            "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
+        ),
+        None => crash!(1, "--bits required for SHA3"),
+    }
+}
+
+/// Creates a SHAKE-128 hasher instance based on the specified bits argument.
+///
+/// # Returns
+///
+/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
+///
+/// # Panics
+///
+/// Panics if the `--bits` flag is missing.
+fn create_shake128(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
+    match matches.get_one::<usize>("bits") {
+        Some(bits) => (
+            "SHAKE128",
+            Box::new(Shake128::new()) as Box<dyn Digest>,
+            *bits,
+        ),
+        None => crash!(1, "--bits required for SHAKE-128"),
+    }
+}
+
+/// Creates a SHAKE-256 hasher instance based on the specified bits argument.
+///
+/// # Returns
+///
+/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
+///
+/// # Panics
+///
+/// Panics if the `--bits` flag is missing.
+fn create_shake256(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
+    match matches.get_one::<usize>("bits") {
+        Some(bits) => (
+            "SHAKE256",
+            Box::new(Shake256::new()) as Box<dyn Digest>,
+            *bits,
+        ),
+        None => crash!(1, "--bits required for SHAKE-256"),
+    }
+}
+
+/// Detects the hash algorithm from the program name or command-line arguments.
+///
+/// # Arguments
+///
+/// * `program` - A string slice containing the program name.
+/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments.
+///
+/// # Returns
+///
+/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
 fn detect_algo(
     program: &str,
     matches: &ArgMatches,
 ) -> (&'static str, Box<dyn Digest + 'static>, usize) {
-    let mut alg: Option<Box<dyn Digest>> = None;
-    let mut name: &'static str = "";
-    let mut output_bits = 0;
-    match program {
+    let (name, alg, output_bits) = match program {
         "md5sum" => ("MD5", Box::new(Md5::new()) as Box<dyn Digest>, 128),
         "sha1sum" => ("SHA1", Box::new(Sha1::new()) as Box<dyn Digest>, 160),
         "sha224sum" => ("SHA224", Box::new(Sha224::new()) as Box<dyn Digest>, 224),
         "sha256sum" => ("SHA256", Box::new(Sha256::new()) as Box<dyn Digest>, 256),
         "sha384sum" => ("SHA384", Box::new(Sha384::new()) as Box<dyn Digest>, 384),
         "sha512sum" => ("SHA512", Box::new(Sha512::new()) as Box<dyn Digest>, 512),
-        "b2sum" => match matches.get_one::<usize>("length") {
-            // by default, blake2 uses 64 bytes (512 bits)
-            // --length=0 falls back to default behavior
-            Some(0) | None => ("BLAKE2", Box::new(Blake2b::new()) as Box<dyn Digest>, 512),
-            Some(length_in_bits) => {
-                if *length_in_bits > 512 {
-                    crash!(1, "Invalid length (maximum digest length is 512 bits)")
-                }
-
-                // blake2 output size must be a multiple of 8 bits
-                if length_in_bits % 8 == 0 {
-                    let length_in_bytes = length_in_bits / 8;
-                    (
-                        "BLAKE2",
-                        Box::new(Blake2b::with_output_bytes(length_in_bytes)),
-                        *length_in_bits,
-                    )
-                } else {
-                    crash!(1, "Invalid length (expected a multiple of 8)")
-                }
-            }
-        },
+        "b2sum" => create_blake2b(matches),
         "b3sum" => ("BLAKE3", Box::new(Blake3::new()) as Box<dyn Digest>, 256),
-        "sha3sum" => match matches.get_one::<usize>("bits") {
-            Some(224) => (
-                "SHA3-224",
-                Box::new(Sha3_224::new()) as Box<dyn Digest>,
-                224,
-            ),
-            Some(256) => (
-                "SHA3-256",
-                Box::new(Sha3_256::new()) as Box<dyn Digest>,
-                256,
-            ),
-            Some(384) => (
-                "SHA3-384",
-                Box::new(Sha3_384::new()) as Box<dyn Digest>,
-                384,
-            ),
-            Some(512) => (
-                "SHA3-512",
-                Box::new(Sha3_512::new()) as Box<dyn Digest>,
-                512,
-            ),
-            Some(_) => crash!(
-                1,
-                "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
-            ),
-            None => crash!(1, "--bits required for SHA3"),
-        },
+        "sha3sum" => create_sha3(matches),
         "sha3-224sum" => (
             "SHA3-224",
             Box::new(Sha3_224::new()) as Box<dyn Digest>,
@@ -858,114 +976,94 @@
             Box::new(Sha3_512::new()) as Box<dyn Digest>,
             512,
         ),
-        "shake128sum" => match matches.get_one::<usize>("bits") {
-            Some(bits) => (
-                "SHAKE128",
-                Box::new(Shake128::new()) as Box<dyn Digest>,
-                *bits,
-            ),
+        "shake128sum" => create_shake128(matches),
+        "shake256sum" => create_shake256(matches),
+        _ => create_algorithm_from_flags(matches),
+    };
+    (name, alg, output_bits)
+}
+
+/// Creates a hasher instance based on the command-line flags.
+///
+/// # Arguments
+///
+/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments.
+///
+/// # Returns
+///
+/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
+///
+/// # Panics
+///
+/// Panics if multiple hash algorithms are specified or if a required flag is missing.
+fn create_algorithm_from_flags(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize) {
+    let mut alg: Option<Box<dyn Digest>> = None;
+    let mut name: &'static str = "";
+    let mut output_bits = 0;
+    let mut set_or_crash = |n, val, bits| {
+        if alg.is_some() {
+            crash!(1, "You cannot combine multiple hash algorithms!");
+        };
+        name = n;
+        alg = Some(val);
+        output_bits = bits;
+    };
+
+    if matches.get_flag("md5") {
+        set_or_crash("MD5", Box::new(Md5::new()), 128);
+    }
+    if matches.get_flag("sha1") {
+        set_or_crash("SHA1", Box::new(Sha1::new()), 160);
+    }
+    if matches.get_flag("sha224") {
+        set_or_crash("SHA224", Box::new(Sha224::new()), 224);
+    }
+    if matches.get_flag("sha256") {
+        set_or_crash("SHA256", Box::new(Sha256::new()), 256);
+    }
+    if matches.get_flag("sha384") {
+        set_or_crash("SHA384", Box::new(Sha384::new()), 384);
+    }
+    if matches.get_flag("sha512") {
+        set_or_crash("SHA512", Box::new(Sha512::new()), 512);
+    }
+    if matches.get_flag("b2sum") {
+        set_or_crash("BLAKE2", Box::new(Blake2b::new()), 512);
+    }
+    if matches.get_flag("b3sum") {
+        set_or_crash("BLAKE3", Box::new(Blake3::new()), 256);
+    }
+    if matches.get_flag("sha3") {
+        let (n, val, bits) = create_sha3(matches);
+        set_or_crash(n, val, bits);
+    }
+    if matches.get_flag("sha3-224") {
+        set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224);
+    }
+    if matches.get_flag("sha3-256") {
+        set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256);
+    }
+    if matches.get_flag("sha3-384") {
+        set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384);
+    }
+    if matches.get_flag("sha3-512") {
+        set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512);
+    }
+    if matches.get_flag("shake128") {
+        match matches.get_one::<usize>("bits") {
+            Some(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), *bits),
             None => crash!(1, "--bits required for SHAKE-128"),
-        },
-        "shake256sum" => match matches.get_one::<usize>("bits") {
-            Some(bits) => (
-                "SHAKE256",
-                Box::new(Shake256::new()) as Box<dyn Digest>,
-                *bits,
-            ),
-            None => crash!(1, "--bits required for SHAKE-256"),
-        },
-        _ => {
-            {
-                let mut set_or_crash = |n, val, bits| {
-                    if alg.is_some() {
-                        crash!(1, "You cannot combine multiple hash algorithms!")
-                    };
-                    name = n;
-                    alg = Some(val);
-                    output_bits = bits;
-                };
-                if matches.get_flag("md5") {
-                    set_or_crash("MD5", Box::new(Md5::new()), 128);
-                }
-                if matches.get_flag("sha1") {
-                    set_or_crash("SHA1", Box::new(Sha1::new()), 160);
-                }
-                if matches.get_flag("sha224") {
-                    set_or_crash("SHA224", Box::new(Sha224::new()), 224);
-                }
-                if matches.get_flag("sha256") {
-                    set_or_crash("SHA256", Box::new(Sha256::new()), 256);
-                }
-                if matches.get_flag("sha384") {
-                    set_or_crash("SHA384", Box::new(Sha384::new()), 384);
-                }
-                if matches.get_flag("sha512") {
-                    set_or_crash("SHA512", Box::new(Sha512::new()), 512);
-                }
-                if matches.get_flag("b2sum") {
-                    set_or_crash("BLAKE2", Box::new(Blake2b::new()), 512);
-                }
-                if matches.get_flag("b3sum") {
-                    set_or_crash("BLAKE3", Box::new(Blake3::new()), 256);
-                }
-                if matches.get_flag("sha3") {
-                    match matches.get_one::<usize>("bits") {
-                        Some(224) => set_or_crash(
-                            "SHA3-224",
-                            Box::new(Sha3_224::new()) as Box<dyn Digest>,
-                            224,
-                        ),
-                        Some(256) => set_or_crash(
-                            "SHA3-256",
-                            Box::new(Sha3_256::new()) as Box<dyn Digest>,
-                            256,
-                        ),
-                        Some(384) => set_or_crash(
-                            "SHA3-384",
-                            Box::new(Sha3_384::new()) as Box<dyn Digest>,
-                            384,
-                        ),
-                        Some(512) => set_or_crash(
-                            "SHA3-512",
-                            Box::new(Sha3_512::new()) as Box<dyn Digest>,
-                            512,
-                        ),
-                        Some(_) => crash!(
-                            1,
-                            "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
-                        ),
-                        None => crash!(1, "--bits required for SHA3"),
-                    }
-                }
-                if matches.get_flag("sha3-224") {
-                    set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224);
-                }
-                if matches.get_flag("sha3-256") {
-                    set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256);
-                }
-                if matches.get_flag("sha3-384") {
-                    set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384);
-                }
-                if matches.get_flag("sha3-512") {
-                    set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512);
-                }
-                if matches.get_flag("shake128") {
-                    match matches.get_one::<usize>("bits") {
-                        Some(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), *bits),
-                        None => crash!(1, "--bits required for SHAKE-128"),
-                    }
-                }
-                if matches.get_flag("shake256") {
-                    match matches.get_one::<usize>("bits") {
-                        Some(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), *bits),
-                        None => crash!(1, "--bits required for SHAKE-256"),
-                    }
-                }
-            }
-            let alg = alg.unwrap_or_else(|| crash!(1, "You must specify hash algorithm!"));
-            (name, alg, output_bits)
         }
     }
+    if matches.get_flag("shake256") {
+        match matches.get_one::<usize>("bits") {
+            Some(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), *bits),
+            None => crash!(1, "--bits required for SHAKE-256"),
+        }
+    }
+
+    let alg = alg.unwrap_or_else(|| crash!(1, "You must specify hash algorithm!"));
+    (name, alg, output_bits)
 }
 
 // TODO: return custom error type
diff --git a/dev/src/uu_install/install.rs.html b/dev/src/uu_install/install.rs.html
index 5d6e3df23..59ea6204b 100644
--- a/dev/src/uu_install/install.rs.html
+++ b/dev/src/uu_install/install.rs.html
@@ -867,6 +867,85 @@
 867
 868
 869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
 
//  * This file is part of the uutils coreutils package.
 //  *
 //  * (c) Ben Eills <ben@beneills.com>
@@ -1551,6 +1630,151 @@
     Ok(())
 }
 
+/// Perform backup before overwriting.
+///
+/// # Parameters
+///
+/// * `to` - The destination file path.
+/// * `b` - The behavior configuration.
+///
+/// # Returns
+///
+/// Returns an Option containing the backup path, or None if backup is not needed.
+///
+fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
+    if to.exists() {
+        if b.verbose {
+            println!("removed {}", to.quote());
+        }
+        let backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix);
+        if let Some(ref backup_path) = backup_path {
+            // TODO!!
+            if let Err(err) = fs::rename(to, backup_path) {
+                return Err(InstallError::BackupFailed(
+                    to.to_path_buf(),
+                    backup_path.to_path_buf(),
+                    err,
+                )
+                .into());
+            }
+        }
+        Ok(backup_path)
+    } else {
+        Ok(None)
+    }
+}
+
+/// Copy a file from one path to another.
+///
+/// # Parameters
+///
+/// * `from` - The source file path.
+/// * `to` - The destination file path.
+///
+/// # Returns
+///
+/// Returns an empty Result or an error in case of failure.
+///
+fn copy_file(from: &Path, to: &Path) -> UResult<()> {
+    if from.as_os_str() == "/dev/null" {
+        /* workaround a limitation of fs::copy
+         * https://github.com/rust-lang/rust/issues/79390
+         */
+        if let Err(err) = File::create(to) {
+            return Err(
+                InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into(),
+            );
+        }
+    } else if let Err(err) = fs::copy(from, to) {
+        return Err(InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into());
+    }
+    Ok(())
+}
+
+/// Strip a file using an external program.
+///
+/// # Parameters
+///
+/// * `to` - The destination file path.
+/// * `b` - The behavior configuration.
+///
+/// # Returns
+///
+/// Returns an empty Result or an error in case of failure.
+///
+fn strip_file(to: &Path, b: &Behavior) -> UResult<()> {
+    match process::Command::new(&b.strip_program).arg(to).output() {
+        Ok(o) => {
+            if !o.status.success() {
+                // Follow GNU's behavior: if strip fails, removes the target
+                let _ = fs::remove_file(to);
+                return Err(InstallError::StripProgramFailed(
+                    String::from_utf8(o.stderr).unwrap_or_default(),
+                )
+                .into());
+            }
+        }
+        Err(e) => {
+            // Follow GNU's behavior: if strip fails, removes the target
+            let _ = fs::remove_file(to);
+            return Err(InstallError::StripProgramFailed(e.to_string()).into());
+        }
+    }
+    Ok(())
+}
+
+/// Set ownership and permissions on the destination file.
+///
+/// # Parameters
+///
+/// * `to` - The destination file path.
+/// * `b` - The behavior configuration.
+///
+/// # Returns
+///
+/// Returns an empty Result or an error in case of failure.
+///
+fn set_ownership_and_permissions(to: &Path, b: &Behavior) -> UResult<()> {
+    // Silent the warning as we want to the error message
+    #[allow(clippy::question_mark)]
+    if mode::chmod(to, b.mode()).is_err() {
+        return Err(InstallError::ChmodFailed(to.to_path_buf()).into());
+    }
+
+    chown_optional_user_group(to, b)?;
+
+    Ok(())
+}
+
+/// Preserve timestamps on the destination file.
+///
+/// # Parameters
+///
+/// * `from` - The source file path.
+/// * `to` - The destination file path.
+///
+/// # Returns
+///
+/// Returns an empty Result or an error in case of failure.
+///
+fn preserve_timestamps(from: &Path, to: &Path) -> UResult<()> {
+    let meta = match fs::metadata(from) {
+        Ok(meta) => meta,
+        Err(e) => return Err(InstallError::MetadataFailed(e).into()),
+    };
+
+    let modified_time = FileTime::from_last_modification_time(&meta);
+    let accessed_time = FileTime::from_last_access_time(&meta);
+
+    match set_file_times(to, accessed_time, modified_time) {
+        Ok(_) => Ok(()),
+        Err(e) => {
+            show_error!("{}", e);
+            Ok(())
+        }
+    }
+}
+
 /// Copy one file to a new location, changing metadata.
 ///
 /// Returns a Result type with the Err variant containing the error message.
@@ -1564,90 +1788,24 @@
 ///
 /// If the copy system call fails, we print a verbose error and return an empty error value.
 ///
-#[allow(clippy::cognitive_complexity)]
 fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> {
     if b.compare && !need_copy(from, to, b)? {
         return Ok(());
     }
     // Declare the path here as we may need it for the verbose output below.
-    let mut backup_path = None;
+    let backup_path = perform_backup(to, b)?;
 
-    // Perform backup, if any, before overwriting 'to'
-    //
-    // The codes actually making use of the backup process don't seem to agree
-    // on how best to approach the issue. (mv and ln, for example)
-    if to.exists() {
-        if b.verbose {
-            println!("removed {}", to.quote());
-        }
-        backup_path = backup_control::get_backup_path(b.backup_mode, to, &b.suffix);
-        if let Some(ref backup_path) = backup_path {
-            // TODO!!
-            if let Err(err) = fs::rename(to, backup_path) {
-                return Err(InstallError::BackupFailed(
-                    to.to_path_buf(),
-                    backup_path.to_path_buf(),
-                    err,
-                )
-                .into());
-            }
-        }
+    copy_file(from, to)?;
+
+    #[cfg(not(windows))]
+    if b.strip {
+        strip_file(to, b)?;
     }
 
-    if from.as_os_str() == "/dev/null" {
-        /* workaround a limitation of fs::copy
-         * https://github.com/rust-lang/rust/issues/79390
-         */
-        if let Err(err) = File::create(to) {
-            return Err(
-                InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into(),
-            );
-        }
-    } else if let Err(err) = fs::copy(from, to) {
-        return Err(InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into());
-    }
-
-    if b.strip && cfg!(not(windows)) {
-        match process::Command::new(&b.strip_program).arg(to).output() {
-            Ok(o) => {
-                if !o.status.success() {
-                    // Follow GNU's behavior: if strip fails, removes the target
-                    let _ = fs::remove_file(to);
-                    return Err(InstallError::StripProgramFailed(
-                        String::from_utf8(o.stderr).unwrap_or_default(),
-                    )
-                    .into());
-                }
-            }
-            Err(e) => {
-                // Follow GNU's behavior: if strip fails, removes the target
-                let _ = fs::remove_file(to);
-                return Err(InstallError::StripProgramFailed(e.to_string()).into());
-            }
-        }
-    }
-
-    // Silent the warning as we want to the error message
-    #[allow(clippy::question_mark)]
-    if mode::chmod(to, b.mode()).is_err() {
-        return Err(InstallError::ChmodFailed(to.to_path_buf()).into());
-    }
-
-    chown_optional_user_group(to, b)?;
+    set_ownership_and_permissions(to, b)?;
 
     if b.preserve_timestamps {
-        let meta = match fs::metadata(from) {
-            Ok(meta) => meta,
-            Err(e) => return Err(InstallError::MetadataFailed(e).into()),
-        };
-
-        let modified_time = FileTime::from_last_modification_time(&meta);
-        let accessed_time = FileTime::from_last_access_time(&meta);
-
-        match set_file_times(to, accessed_time, modified_time) {
-            Ok(_) => {}
-            Err(e) => show_error!("{}", e),
-        }
+        preserve_timestamps(from, to)?;
     }
 
     if b.verbose {
diff --git a/dev/src/uu_stat/stat.rs.html b/dev/src/uu_stat/stat.rs.html
index 617a36a3e..d5b2e7da2 100644
--- a/dev/src/uu_stat/stat.rs.html
+++ b/dev/src/uu_stat/stat.rs.html
@@ -933,6 +933,110 @@
 933
 934
 935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
 
// This file is part of the uutils coreutils package.
 //
 // (c) Jian Zeng <anonymousknight96@gmail.com>
@@ -1140,7 +1244,16 @@
     default_dev_tokens: Vec<Token>,
 }
 
-#[allow(clippy::cognitive_complexity)]
+/// Prints a formatted output based on the provided output type, flags, width, and precision.
+///
+/// # Arguments
+///
+/// * `output` - A reference to the OutputType enum containing the value to be printed.
+/// * `flags` - A Flags struct containing formatting flags.
+/// * `width` - The width of the field for the printed output.
+/// * `precision` - An Option containing the precision value.
+///
+/// This function delegates the printing process to more specialized functions depending on the output type.
 fn print_it(output: &OutputType, flags: Flags, width: usize, precision: Option<usize>) {
     // If the precision is given as just '.', the precision is taken to be zero.
     // A negative precision is taken as if the precision were omitted.
@@ -1171,71 +1284,166 @@
     // A sign (+ or -) should always be placed before a number produced by a signed conversion.
     // By default, a sign  is  used only for negative numbers.
     // A + overrides a space if both are used.
-
-    let padding_char = if flags.zero && !flags.left && precision.is_none() {
-        Padding::Zero
-    } else {
-        Padding::Space
-    };
+    let padding_char = determine_padding_char(&flags, &precision);
 
     match output {
-        OutputType::Str(s) => {
-            let s = match precision {
-                Some(p) if p < s.len() => &s[..p],
-                _ => s,
-            };
-            pad_and_print(s, flags.left, width, Padding::Space);
-        }
-        OutputType::Integer(num) => {
-            let num = num.to_string();
-            let arg = if flags.group {
-                group_num(&num)
-            } else {
-                Cow::Borrowed(num.as_str())
-            };
-            let prefix = if flags.sign {
-                "+"
-            } else if flags.space {
-                " "
-            } else {
-                ""
-            };
-            let extended = format!(
-                "{prefix}{arg:0>precision$}",
-                precision = precision.unwrap_or(0)
-            );
-            pad_and_print(&extended, flags.left, width, padding_char);
-        }
-        OutputType::Unsigned(num) => {
-            let num = num.to_string();
-            let s = if flags.group {
-                group_num(&num)
-            } else {
-                Cow::Borrowed(num.as_str())
-            };
-            let s = format!("{s:0>precision$}", precision = precision.unwrap_or(0));
-            pad_and_print(&s, flags.left, width, padding_char);
-        }
+        OutputType::Str(s) => print_str(s, &flags, width, precision),
+        OutputType::Integer(num) => print_integer(*num, &flags, width, precision, padding_char),
+        OutputType::Unsigned(num) => print_unsigned(*num, &flags, width, precision, padding_char),
         OutputType::UnsignedOct(num) => {
-            let prefix = if flags.alter { "0" } else { "" };
-            let s = format!(
-                "{prefix}{num:0>precision$o}",
-                precision = precision.unwrap_or(0)
-            );
-            pad_and_print(&s, flags.left, width, padding_char);
+            print_unsigned_oct(*num, &flags, width, precision, padding_char);
         }
         OutputType::UnsignedHex(num) => {
-            let prefix = if flags.alter { "0x" } else { "" };
-            let s = format!(
-                "{prefix}{num:0>precision$x}",
-                precision = precision.unwrap_or(0)
-            );
-            pad_and_print(&s, flags.left, width, padding_char);
+            print_unsigned_hex(*num, &flags, width, precision, padding_char);
         }
         OutputType::Unknown => print!("?"),
     }
 }
 
+/// Determines the padding character based on the provided flags and precision.
+///
+/// # Arguments
+///
+/// * `flags` - A reference to the Flags struct containing formatting flags.
+/// * `precision` - An Option containing the precision value.
+///
+/// # Returns
+///
+/// * Padding - An instance of the Padding enum representing the padding character.
+fn determine_padding_char(flags: &Flags, precision: &Option<usize>) -> Padding {
+    if flags.zero && !flags.left && precision.is_none() {
+        Padding::Zero
+    } else {
+        Padding::Space
+    }
+}
+
+/// Prints a string value based on the provided flags, width, and precision.
+///
+/// # Arguments
+///
+/// * `s` - The string to be printed.
+/// * `flags` - A reference to the Flags struct containing formatting flags.
+/// * `width` - The width of the field for the printed string.
+/// * `precision` - An Option containing the precision value.
+fn print_str(s: &str, flags: &Flags, width: usize, precision: Option<usize>) {
+    let s = match precision {
+        Some(p) if p < s.len() => &s[..p],
+        _ => s,
+    };
+    pad_and_print(s, flags.left, width, Padding::Space);
+}
+
+/// Prints an integer value based on the provided flags, width, and precision.
+///
+/// # Arguments
+///
+/// * `num` - The integer value to be printed.
+/// * `flags` - A reference to the Flags struct containing formatting flags.
+/// * `width` - The width of the field for the printed integer.
+/// * `precision` - An Option containing the precision value.
+/// * `padding_char` - The padding character as determined by `determine_padding_char`.
+fn print_integer(
+    num: i64,
+    flags: &Flags,
+    width: usize,
+    precision: Option<usize>,
+    padding_char: Padding,
+) {
+    let num = num.to_string();
+    let arg = if flags.group {
+        group_num(&num)
+    } else {
+        Cow::Borrowed(num.as_str())
+    };
+    let prefix = if flags.sign {
+        "+"
+    } else if flags.space {
+        " "
+    } else {
+        ""
+    };
+    let extended = format!(
+        "{prefix}{arg:0>precision$}",
+        precision = precision.unwrap_or(0)
+    );
+    pad_and_print(&extended, flags.left, width, padding_char);
+}
+
+/// Prints an unsigned integer value based on the provided flags, width, and precision.
+///
+/// # Arguments
+///
+/// * `num` - The unsigned integer value to be printed.
+/// * `flags` - A reference to the Flags struct containing formatting flags.
+/// * `width` - The width of the field for the printed unsigned integer.
+/// * `precision` - An Option containing the precision value.
+/// * `padding_char` - The padding character as determined by `determine_padding_char`.
+fn print_unsigned(
+    num: u64,
+    flags: &Flags,
+    width: usize,
+    precision: Option<usize>,
+    padding_char: Padding,
+) {
+    let num = num.to_string();
+    let s = if flags.group {
+        group_num(&num)
+    } else {
+        Cow::Borrowed(num.as_str())
+    };
+    let s = format!("{s:0>precision$}", precision = precision.unwrap_or(0));
+    pad_and_print(&s, flags.left, width, padding_char);
+}
+
+/// Prints an unsigned octal integer value based on the provided flags, width, and precision.
+///
+/// # Arguments
+///
+/// * `num` - The unsigned octal integer value to be printed.
+/// * `flags` - A reference to the Flags struct containing formatting flags.
+/// * `width` - The width of the field for the printed unsigned octal integer.
+/// * `precision` - An Option containing the precision value.
+/// * `padding_char` - The padding character as determined by `determine_padding_char`.
+fn print_unsigned_oct(
+    num: u32,
+    flags: &Flags,
+    width: usize,
+    precision: Option<usize>,
+    padding_char: Padding,
+) {
+    let prefix = if flags.alter { "0" } else { "" };
+    let s = format!(
+        "{prefix}{num:0>precision$o}",
+        precision = precision.unwrap_or(0)
+    );
+    pad_and_print(&s, flags.left, width, padding_char);
+}
+
+/// Prints an unsigned hexadecimal integer value based on the provided flags, width, and precision.
+///
+/// # Arguments
+///
+/// * `num` - The unsigned hexadecimal integer value to be printed.
+/// * `flags` - A reference to the Flags struct containing formatting flags.
+/// * `width` - The width of the field for the printed unsigned hexadecimal integer.
+/// * `precision` - An Option containing the precision value.
+/// * `padding_char` - The padding character as determined by `determine_padding_char`.
+fn print_unsigned_hex(
+    num: u64,
+    flags: &Flags,
+    width: usize,
+    precision: Option<usize>,
+    padding_char: Padding,
+) {
+    let prefix = if flags.alter { "0x" } else { "" };
+    let s = format!(
+        "{prefix}{num:0>precision$x}",
+        precision = precision.unwrap_or(0)
+    );
+    pad_and_print(&s, flags.left, width, padding_char);
+}
+
 impl Stater {
     fn generate_tokens(format_str: &str, use_printf: bool) -> UResult<Vec<Token>> {
         let mut tokens = Vec::new();
diff --git a/dev/uu_fmt/fn.uu_app.html b/dev/uu_fmt/fn.uu_app.html
index 663fb860b..0bdef4273 100644
--- a/dev/uu_fmt/fn.uu_app.html
+++ b/dev/uu_fmt/fn.uu_app.html
@@ -1 +1 @@
-uu_app in uu_fmt - Rust

Function uu_fmt::uu_app

source ·
pub fn uu_app() -> Command
\ No newline at end of file +uu_app in uu_fmt - Rust

Function uu_fmt::uu_app

source ·
pub fn uu_app() -> Command
\ No newline at end of file diff --git a/dev/uu_fmt/fn.uumain.html b/dev/uu_fmt/fn.uumain.html index aaa304924..cc1049a2d 100644 --- a/dev/uu_fmt/fn.uumain.html +++ b/dev/uu_fmt/fn.uumain.html @@ -1 +1 @@ -uumain in uu_fmt - Rust

Function uu_fmt::uumain

source ·
pub fn uumain(args: impl Args) -> i32
\ No newline at end of file +uumain in uu_fmt - Rust

Function uu_fmt::uumain

source ·
pub fn uumain(args: impl Args) -> i32
\ No newline at end of file diff --git a/dev/uu_fmt/index.html b/dev/uu_fmt/index.html index 6fba6125d..fb78fd92f 100644 --- a/dev/uu_fmt/index.html +++ b/dev/uu_fmt/index.html @@ -1 +1 @@ -uu_fmt - Rust
\ No newline at end of file +uu_fmt - Rust
\ No newline at end of file diff --git a/dev/uu_hashsum/fn.uu_app_b3sum.html b/dev/uu_hashsum/fn.uu_app_b3sum.html index aa883ff80..a4d2cbf78 100644 --- a/dev/uu_hashsum/fn.uu_app_b3sum.html +++ b/dev/uu_hashsum/fn.uu_app_b3sum.html @@ -1 +1 @@ -uu_app_b3sum in uu_hashsum - Rust

Function uu_hashsum::uu_app_b3sum

source ·
pub fn uu_app_b3sum() -> Command
\ No newline at end of file +uu_app_b3sum in uu_hashsum - Rust

Function uu_hashsum::uu_app_b3sum

source ·
pub fn uu_app_b3sum() -> Command
\ No newline at end of file diff --git a/dev/uu_hashsum/fn.uu_app_bits.html b/dev/uu_hashsum/fn.uu_app_bits.html index 191cd9dc9..4417acc3b 100644 --- a/dev/uu_hashsum/fn.uu_app_bits.html +++ b/dev/uu_hashsum/fn.uu_app_bits.html @@ -1 +1 @@ -uu_app_bits in uu_hashsum - Rust

Function uu_hashsum::uu_app_bits

source ·
pub fn uu_app_bits() -> Command
\ No newline at end of file +uu_app_bits in uu_hashsum - Rust

Function uu_hashsum::uu_app_bits

source ·
pub fn uu_app_bits() -> Command
\ No newline at end of file diff --git a/dev/uu_hashsum/fn.uu_app_common.html b/dev/uu_hashsum/fn.uu_app_common.html index f3b59412e..69a7dc931 100644 --- a/dev/uu_hashsum/fn.uu_app_common.html +++ b/dev/uu_hashsum/fn.uu_app_common.html @@ -1 +1 @@ -uu_app_common in uu_hashsum - Rust

Function uu_hashsum::uu_app_common

source ·
pub fn uu_app_common() -> Command
\ No newline at end of file +uu_app_common in uu_hashsum - Rust

Function uu_hashsum::uu_app_common

source ·
pub fn uu_app_common() -> Command
\ No newline at end of file diff --git a/dev/uu_hashsum/fn.uu_app_custom.html b/dev/uu_hashsum/fn.uu_app_custom.html index 3fdc5179a..3bc68993e 100644 --- a/dev/uu_hashsum/fn.uu_app_custom.html +++ b/dev/uu_hashsum/fn.uu_app_custom.html @@ -1 +1 @@ -uu_app_custom in uu_hashsum - Rust

Function uu_hashsum::uu_app_custom

source ·
pub fn uu_app_custom() -> Command
\ No newline at end of file +uu_app_custom in uu_hashsum - Rust

Function uu_hashsum::uu_app_custom

source ·
pub fn uu_app_custom() -> Command
\ No newline at end of file diff --git a/dev/uu_hashsum/fn.uu_app_length.html b/dev/uu_hashsum/fn.uu_app_length.html index 71034ed05..5a305b52b 100644 --- a/dev/uu_hashsum/fn.uu_app_length.html +++ b/dev/uu_hashsum/fn.uu_app_length.html @@ -1 +1 @@ -uu_app_length in uu_hashsum - Rust

Function uu_hashsum::uu_app_length

source ·
pub fn uu_app_length() -> Command
\ No newline at end of file +uu_app_length in uu_hashsum - Rust

Function uu_hashsum::uu_app_length

source ·
pub fn uu_app_length() -> Command
\ No newline at end of file diff --git a/dev/uu_hashsum/fn.uumain.html b/dev/uu_hashsum/fn.uumain.html index 9f9a226bd..a47f5907a 100644 --- a/dev/uu_hashsum/fn.uumain.html +++ b/dev/uu_hashsum/fn.uumain.html @@ -1 +1 @@ -uumain in uu_hashsum - Rust

Function uu_hashsum::uumain

source ·
pub fn uumain(args: impl Args) -> i32
\ No newline at end of file +uumain in uu_hashsum - Rust

Function uu_hashsum::uumain

source ·
pub fn uumain(args: impl Args) -> i32
\ No newline at end of file diff --git a/dev/uu_hashsum/index.html b/dev/uu_hashsum/index.html index 5f46be8a2..309f6ecf7 100644 --- a/dev/uu_hashsum/index.html +++ b/dev/uu_hashsum/index.html @@ -1 +1 @@ -uu_hashsum - Rust
\ No newline at end of file +uu_hashsum - Rust
\ No newline at end of file diff --git a/dev/uu_install/index.html b/dev/uu_install/index.html index 0c0c52ef1..021e86a0d 100644 --- a/dev/uu_install/index.html +++ b/dev/uu_install/index.html @@ -1 +1 @@ -uu_install - Rust
\ No newline at end of file +uu_install - Rust
\ No newline at end of file diff --git a/dev/uu_stat/fn.uu_app.html b/dev/uu_stat/fn.uu_app.html index e7c29d526..cee80f30f 100644 --- a/dev/uu_stat/fn.uu_app.html +++ b/dev/uu_stat/fn.uu_app.html @@ -1 +1 @@ -uu_app in uu_stat - Rust

Function uu_stat::uu_app

source ·
pub fn uu_app() -> Command
\ No newline at end of file +uu_app in uu_stat - Rust

Function uu_stat::uu_app

source ·
pub fn uu_app() -> Command
\ No newline at end of file diff --git a/dev/uu_stat/fn.uumain.html b/dev/uu_stat/fn.uumain.html index af358213e..dad483454 100644 --- a/dev/uu_stat/fn.uumain.html +++ b/dev/uu_stat/fn.uumain.html @@ -1 +1 @@ -uumain in uu_stat - Rust

Function uu_stat::uumain

source ·
pub fn uumain(args: impl Args) -> i32
\ No newline at end of file +uumain in uu_stat - Rust

Function uu_stat::uumain

source ·
pub fn uumain(args: impl Args) -> i32
\ No newline at end of file diff --git a/dev/uu_stat/index.html b/dev/uu_stat/index.html index dc6795edb..5ba2fd4c5 100644 --- a/dev/uu_stat/index.html +++ b/dev/uu_stat/index.html @@ -1 +1 @@ -uu_stat - Rust
\ No newline at end of file +uu_stat - Rust
\ No newline at end of file