diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8532279..56188b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,7 @@ jobs: env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: "" - RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" + RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" RUSTDOCFLAGS: "-Cpanic=abort" - name: "`grcov` ~ install" id: build_grcov diff --git a/Cargo.lock b/Cargo.lock index 629738d..a79d2ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,6 +71,17 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -85,18 +96,18 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "clap" -version = "4.5.10" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6b81fb3c84f5563d509c59b5a48d935f689e993afa90fe39047f05adef9142" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.10" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca6706fd5224857d9ac5eb9355f6683563cc0541c7cd9d014043b57cbec78ac" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstream", "anstyle", @@ -107,9 +118,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.9" +version = "4.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa2032320fd6f50d22af510d204b2994eef49600dfbd0e771a166213844e4cd" +checksum = "a8670053e87c316345e384ca1f3eba3006fc6355ed8b8a1140d104e109e3df34" dependencies = [ "clap", ] @@ -122,9 +133,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clap_mangen" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50dde5bc0c853d6248de457e5eb6e5a674a54b93810a34ded88d882ca1fe2de" +checksum = "f17415fd4dfbea46e3274fcd8d368284519b358654772afb700dc2e8d2b24eeb" dependencies = [ "clap", "roff", @@ -632,15 +643,15 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.13" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +checksum = "29a6b037e3af4ae9a9d6214198e4df53091363b2c96c88fc416a6c1bd92a2799" dependencies = [ - "cfg-if", + "bstr", "core-foundation-sys", "libc", + "memchr", "ntapi", - "once_cell", "rayon", "windows", ] @@ -767,6 +778,7 @@ dependencies = [ "uu_ctrlaltdel", "uu_last", "uu_lscpu", + "uu_lsmem", "uu_mountpoint", "uu_rev", "uucore", @@ -800,6 +812,14 @@ dependencies = [ "uucore", ] +[[package]] +name = "uu_lsmem" +version = "0.0.1" +dependencies = [ + "clap", + "uucore", +] + [[package]] name = "uu_mountpoint" version = "0.0.1" @@ -891,21 +911,55 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ "windows-core", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-targets 0.52.0", + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -923,7 +977,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -943,17 +997,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -964,9 +1019,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -976,9 +1031,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -988,9 +1043,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -1000,9 +1061,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -1012,9 +1073,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -1024,9 +1085,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -1036,9 +1097,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "xattr" diff --git a/Cargo.toml b/Cargo.toml index 0895d59..d165c0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ uudoc = [] feat_common_core = [ "mountpoint", "lscpu", + "lsmem", "ctrlaltdel", "rev", "last" @@ -39,7 +40,7 @@ clap = { version = "4.4", features = ["wrap_help", "cargo"] } clap_complete = "4.4" clap_mangen = "0.2" regex = "1.10.2" -sysinfo = "0.30" +sysinfo = "0.31" libc = "0.2.152" phf = "0.11.2" phf_codegen = "0.11.2" @@ -60,6 +61,7 @@ dns-lookup = { workspace = true } # lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" } +lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/uu/lsmem" } mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" } ctrlaltdel = { optional = true, version = "0.0.1", package = "uu_ctrlaltdel", path = "src/uu/ctrlaltdel" } rev = { optional = true, version = "0.0.1", package = "uu_rev", path = "src/uu/rev" } diff --git a/src/uu/lscpu/Cargo.toml b/src/uu/lscpu/Cargo.toml index c59e07e..60b38f1 100644 --- a/src/uu/lscpu/Cargo.toml +++ b/src/uu/lscpu/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" path = "src/lscpu.rs" [[bin]] -name = "mountpoint" +name = "lscpu" path = "src/main.rs" [dependencies] diff --git a/src/uu/lscpu/src/lscpu.rs b/src/uu/lscpu/src/lscpu.rs index 2faacf9..001ae36 100644 --- a/src/uu/lscpu/src/lscpu.rs +++ b/src/uu/lscpu/src/lscpu.rs @@ -16,7 +16,6 @@ const USAGE: &str = help_usage!("lscpu.md"); pub fn uumain(args: impl uucore::Args) -> UResult<()> { let _matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; let system = System::new_all(); - let _cpu = system.global_cpu_info(); println!("Architecture: {}", get_architecture()); println!("CPU(s): {}", system.cpus().len()); diff --git a/src/uu/lsmem/Cargo.toml b/src/uu/lsmem/Cargo.toml new file mode 100644 index 0000000..a76660a --- /dev/null +++ b/src/uu/lsmem/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "uu_lsmem" +version = "0.0.1" +edition = "2021" + +[lib] +path = "src/lsmem.rs" + +[[bin]] +name = "lsmem" +path = "src/main.rs" + +[dependencies] +uucore = { workspace = true } +clap = { workspace = true } diff --git a/src/uu/lsmem/lsmem.md b/src/uu/lsmem/lsmem.md new file mode 100644 index 0000000..7903bbd --- /dev/null +++ b/src/uu/lsmem/lsmem.md @@ -0,0 +1,7 @@ +# lsmem + +``` +lsmem [OPTION]... +``` + +List the ranges of available memory with their online status. diff --git a/src/uu/lsmem/src/lsmem.rs b/src/uu/lsmem/src/lsmem.rs new file mode 100644 index 0000000..d8f3388 --- /dev/null +++ b/src/uu/lsmem/src/lsmem.rs @@ -0,0 +1,24 @@ +// This file is part of the uutils util-linux package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use clap::{crate_version, Command}; +use uucore::{error::UResult, format_usage, help_about, help_usage}; + +const ABOUT: &str = help_about!("lsmem.md"); +const USAGE: &str = help_usage!("lsmem.md"); + +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let _matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; + Ok(()) +} + +pub fn uu_app() -> Command { + Command::new(uucore::util_name()) + .version(crate_version!()) + .about(ABOUT) + .override_usage(format_usage(USAGE)) + .infer_long_args(true) +} diff --git a/src/uu/lsmem/src/main.rs b/src/uu/lsmem/src/main.rs new file mode 100644 index 0000000..33561cd --- /dev/null +++ b/src/uu/lsmem/src/main.rs @@ -0,0 +1 @@ +uucore::bin!(uu_lsmem); diff --git a/src/uu/rev/src/rev.rs b/src/uu/rev/src/rev.rs index 75e56fe..b980d16 100644 --- a/src/uu/rev/src/rev.rs +++ b/src/uu/rev/src/rev.rs @@ -12,53 +12,55 @@ use uucore::{error::UResult, format_usage, help_about, help_usage}; const ABOUT: &str = help_about!("rev.md"); const USAGE: &str = help_usage!("rev.md"); +mod options { + pub const FILE: &str = "file"; + pub const ZERO: &str = "zero"; +} + #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; - let files = matches.get_many::("file"); + let files = matches.get_many::(options::FILE); + let zero = matches.get_flag(options::ZERO); + + let sep = if zero { b'\0' } else { b'\n' }; - match files { - Some(files) => { - for path in files { - let file = match std::fs::File::open(path) { - Ok(val) => val, - Err(err) => { - uucore::error::set_exit_code(1); - uucore::show_error!("cannot open {}: {}", path, err); - continue; - } - }; - if let Err(err) = rev_stream(file) { - uucore::error::set_exit_code(1); - uucore::show_error!("cannot read {}: {}", path, err); - } + if let Some(files) = files { + for path in files { + let Ok(file) = std::fs::File::open(path) else { + uucore::error::set_exit_code(1); + uucore::show_error!("cannot open {path}: No such file or directory"); + continue; + }; + if let Err(err) = rev_stream(file, sep) { + uucore::error::set_exit_code(1); + uucore::show_error!("cannot read {path}: {err}"); } } - None => { - let stdin = std::io::stdin().lock(); - let _ = rev_stream(stdin); - } + } else { + let stdin = std::io::stdin().lock(); + let _ = rev_stream(stdin, sep); } Ok(()) } -fn rev_stream(stream: impl Read) -> std::io::Result<()> { +fn rev_stream(stream: impl Read, sep: u8) -> std::io::Result<()> { let mut stdout = std::io::stdout().lock(); let mut stream = BufReader::new(stream); let mut buf = Vec::with_capacity(4096); loop { buf.clear(); - stream.read_until(b'\n', &mut buf)?; - if buf.last().copied() != Some(b'\n') { + stream.read_until(sep, &mut buf)?; + if buf.last().copied() == Some(sep) { + buf.pop(); buf.reverse(); + buf.push(sep); stdout.write_all(&buf)?; - break; } else { - buf.pop(); buf.reverse(); - buf.push(b'\n'); stdout.write_all(&buf)?; + break; } } Ok(()) @@ -71,11 +73,18 @@ pub fn uu_app() -> Command { .override_usage(format_usage(USAGE)) .infer_long_args(true) .arg( - Arg::new("file") + Arg::new(options::FILE) .value_name("FILE") .help("Paths of files to reverse") .index(1) .action(ArgAction::Set) .num_args(1..), ) + .arg( + Arg::new(options::ZERO) + .short('0') + .long("zero") + .help("Zero termination. Use the byte '\\0' as line separator.") + .action(ArgAction::SetTrue), + ) } diff --git a/tests/by-util/test_lsmem.rs b/tests/by-util/test_lsmem.rs new file mode 100644 index 0000000..33c603c --- /dev/null +++ b/tests/by-util/test_lsmem.rs @@ -0,0 +1,4 @@ +// This file is part of the uutils util-linux package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. diff --git a/tests/by-util/test_rev.rs b/tests/by-util/test_rev.rs index ac8f594..6fe7335 100644 --- a/tests/by-util/test_rev.rs +++ b/tests/by-util/test_rev.rs @@ -9,3 +9,74 @@ use crate::common::util::TestScenario; fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails().code_is(1); } + +#[test] +fn test_piped_in_data() { + new_ucmd!().pipe_in("a test").succeeds().stdout_is("tset a"); +} + +#[test] +fn test_existing_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.write("a.txt", "line A\nline B"); + + ucmd.arg("a.txt").succeeds().stdout_is("A enil\nB enil"); +} + +#[test] +fn test_zero() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.write("a.txt", "line A\0line B"); + + ucmd.arg("a.txt") + .arg("--zero") + .succeeds() + .stdout_is("A enil\0B enil"); +} + +#[test] +fn test_multiple_files() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.write("a.txt", "file A\n"); + at.write("b.txt", "file B\n"); + + ucmd.args(&["a.txt", "b.txt"]) + .succeeds() + .stdout_is("A elif\nB elif\n"); +} + +#[test] +fn test_empty_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.touch("empty.txt"); + + ucmd.arg("empty.txt").succeeds().no_output(); +} + +#[test] +fn test_non_existing_file() { + new_ucmd!() + .arg("non_existing_file") + .fails() + .code_is(1) + .no_stdout() + .stderr_contains("cannot open non_existing_file: No such file or directory"); +} + +#[test] +fn test_non_existing_and_existing_file() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.write("a.txt", "file A"); + + ucmd.arg("non_existing_file") + .arg("a.txt") + .fails() + .code_is(1) + .stderr_contains("cannot open non_existing_file: No such file or directory") + .stdout_is("A elif"); +}