From b66945dee85ec536bc04de6062bebaaad7ed72ee Mon Sep 17 00:00:00 2001 From: Koutheir Attouchi Date: Mon, 24 Feb 2025 13:40:14 -0500 Subject: [PATCH] Configure command line parsing. --- Cargo.lock | 188 +++++++++++++-------------- Cargo.toml | 3 + src/uu/chcpu/Cargo.toml | 16 +++ src/uu/chcpu/chcpu.md | 11 ++ src/uu/chcpu/src/chcpu.rs | 257 +++++++++++++++++++++++++++++++++++++ src/uu/chcpu/src/errors.rs | 44 +++++++ src/uu/chcpu/src/main.rs | 1 + 7 files changed, 423 insertions(+), 97 deletions(-) create mode 100644 src/uu/chcpu/Cargo.toml create mode 100644 src/uu/chcpu/chcpu.md create mode 100644 src/uu/chcpu/src/chcpu.rs create mode 100644 src/uu/chcpu/src/errors.rs create mode 100644 src/uu/chcpu/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 8a41289..246399e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,9 +84,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "block-buffer" @@ -103,17 +103,11 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "cc" -version = "1.2.13" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "shlex", ] @@ -261,9 +255,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -298,15 +292,15 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -315,7 +309,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -336,14 +330,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", + "r-efi", "wasi", - "windows-targets 0.52.6", ] [[package]] @@ -389,9 +383,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", @@ -405,9 +399,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" @@ -439,9 +433,9 @@ checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "md-5" @@ -521,9 +515,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "os_display" @@ -600,11 +594,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -619,9 +613,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -650,13 +644,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -673,8 +673,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha", - "rand_core 0.9.0", - "zerocopy 0.8.17", + "rand_core 0.9.3", + "zerocopy", ] [[package]] @@ -684,7 +684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -695,14 +695,19 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "rand_core" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", - "zerocopy 0.8.17", ] +[[package]] +name = "rangemap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" + [[package]] name = "rayon" version = "1.10.0" @@ -777,33 +782,33 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustix" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8dcd64f141950290e45c99f7710ede1b600297c91818bb30b3667c0f45dc0" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys 0.9.3", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "serde" @@ -874,9 +879,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -906,17 +911,17 @@ dependencies = [ "fastrand", "getrandom", "once_cell", - "rustix 1.0.0", - "windows-sys 0.52.0", + "rustix 1.0.3", + "windows-sys 0.59.0", ] [[package]] name = "terminal_size" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix 0.38.44", + "rustix 1.0.3", "windows-sys 0.59.0", ] @@ -934,9 +939,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" dependencies = [ "deranged", "itoa", @@ -951,15 +956,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" dependencies = [ "num-conv", "time-core", @@ -973,9 +978,9 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-linebreak" @@ -1023,6 +1028,7 @@ dependencies = [ "tempfile", "textwrap", "uu_blockdev", + "uu_chcpu", "uu_ctrlaltdel", "uu_dmesg", "uu_fsfreeze", @@ -1051,6 +1057,15 @@ dependencies = [ "uucore", ] +[[package]] +name = "uu_chcpu" +version = "0.0.1" +dependencies = [ + "clap", + "rangemap", + "uucore", +] + [[package]] name = "uu_ctrlaltdel" version = "0.0.1" @@ -1223,9 +1238,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -1374,9 +1389,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-result" @@ -1537,9 +1552,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] @@ -1551,7 +1566,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" dependencies = [ "libc", - "rustix 1.0.0", + "rustix 1.0.3", ] [[package]] @@ -1562,39 +1577,18 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" dependencies = [ - "byteorder", - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713" -dependencies = [ - "zerocopy-derive 0.8.17", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 5bad5d9..402688a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ uudoc = [] feat_common_core = [ "blockdev", + "chcpu", "ctrlaltdel", "dmesg", "fsfreeze", @@ -62,6 +63,7 @@ tempfile = "3.9.0" textwrap = { version = "0.16.0", features = ["terminal_size"] } uucore = "0.0.30" xattr = "1.3.1" +rangemap = "1.5.1" [dependencies] clap = { workspace = true } @@ -76,6 +78,7 @@ uucore = { workspace = true } # blockdev = { optional = true, version = "0.0.1", package = "uu_blockdev", path = "src/uu/blockdev" } +chcpu = { optional = true, version = "0.0.1", package = "uu_chcpu", path = "src/uu/chcpu" } ctrlaltdel = { optional = true, version = "0.0.1", package = "uu_ctrlaltdel", path = "src/uu/ctrlaltdel" } dmesg = { optional = true, version = "0.0.1", package = "uu_dmesg", path = "src/uu/dmesg" } fsfreeze = { optional = true, version = "0.0.1", package = "uu_fsfreeze", path = "src/uu/fsfreeze" } diff --git a/src/uu/chcpu/Cargo.toml b/src/uu/chcpu/Cargo.toml new file mode 100644 index 0000000..afaefed --- /dev/null +++ b/src/uu/chcpu/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "uu_chcpu" +version = "0.0.1" +edition = "2024" + +[lib] +path = "src/chcpu.rs" + +[[bin]] +name = "chcpu" +path = "src/main.rs" + +[dependencies] +uucore = { workspace = true } +clap = { workspace = true } +rangemap = { workspace = true } diff --git a/src/uu/chcpu/chcpu.md b/src/uu/chcpu/chcpu.md new file mode 100644 index 0000000..14d273a --- /dev/null +++ b/src/uu/chcpu/chcpu.md @@ -0,0 +1,11 @@ +# chcpu + +``` +chcpu {-e|--enable|-d|--disable|-c|--configure|-g|--deconfigure} cpu-list +chcpu {-p|--dispatch} mode +chcpu {-r|--rescan} +chcpu {-V|--version} +chcpu {-h|--help} +``` + +configure CPUs in a multi-processor system. diff --git a/src/uu/chcpu/src/chcpu.rs b/src/uu/chcpu/src/chcpu.rs new file mode 100644 index 0000000..803802e --- /dev/null +++ b/src/uu/chcpu/src/chcpu.rs @@ -0,0 +1,257 @@ +// 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. + +mod errors; + +use std::str::FromStr; + +use clap::builder::{EnumValueParser, PossibleValue}; +use clap::{Arg, ArgAction, ArgGroup, Command, ValueEnum, crate_version}; +use rangemap::RangeInclusiveSet; +use uucore::{error::UResult, format_usage, help_about, help_usage}; + +use crate::errors::ChCpuError; + +mod options { + pub static ENABLE: &str = "enable"; + pub static DISABLE: &str = "disable"; + pub static CONFIGURE: &str = "configure"; + pub static DECONFIGURE: &str = "deconfigure"; + pub static CPU_LIST: &str = "cpu-list"; + pub static DISPATCH: &str = "dispatch"; + pub static MODE: &str = "mode"; + pub static RESCAN: &str = "rescan"; +} + +const ABOUT: &str = help_about!("chcpu.md"); +const USAGE: &str = help_usage!("chcpu.md"); + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +enum DispatchMode { + Horizontal, + Vertical, +} + +impl ValueEnum for DispatchMode { + fn value_variants<'a>() -> &'a [Self] { + &[Self::Horizontal, Self::Vertical] + } + + fn to_possible_value<'a>(&self) -> Option { + Some(match self { + Self::Horizontal => { + PossibleValue::new("horizontal").help("workload spread across all available CPUs") + } + Self::Vertical => { + PossibleValue::new("vertical").help("workload concentrated on few CPUs") + } + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +struct CpuList(RangeInclusiveSet); + +impl FromStr for CpuList { + type Err = ChCpuError; + + fn from_str(s: &str) -> Result { + let set: RangeInclusiveSet = s + .split(',') + .map(|element| { + // Parsing: ...,element,... + let mut iter = element.splitn(2, '-').map(str::trim); + let first = iter.next(); + (first, iter.next()) + }) + .map(|(first, last)| { + let first: usize = first + .ok_or(ChCpuError::EmptyCpuList)? + .parse() + .map_err(|_r| ChCpuError::CpuSpecNotPositiveInteger)?; + + if let Some(last) = last { + // Parsing: ...,first-last,... + let last = + str::parse(last).map_err(|_r| ChCpuError::CpuSpecNotPositiveInteger)?; + + if first <= last { + Ok(first..=last) + } else { + Err(ChCpuError::CpuSpecFirstAfterLast) + } + } else { + Ok(first..=first) // Parsing: ...,first,... + } + }) + .collect::>()?; + + if set.is_empty() { + Err(ChCpuError::EmptyCpuList) + } else { + Ok(Self(set)) + } + } +} + +fn enable_cpu_list(_cpu_list: &CpuList) -> UResult<()> { + dbg!(_cpu_list); + todo!() +} + +fn disable_cpu_list(_cpu_list: &CpuList) -> UResult<()> { + dbg!(_cpu_list); + todo!() +} + +fn configure_cpu_list(_cpu_list: &CpuList) -> UResult<()> { + dbg!(_cpu_list); + todo!() +} + +fn deconfigure_cpu_list(_cpu_list: &CpuList) -> UResult<()> { + dbg!(_cpu_list); + todo!() +} + +fn set_dispatch_mode(_mode: DispatchMode) -> UResult<()> { + dbg!(_mode); + todo!() +} + +fn rescan_cpus() -> UResult<()> { + todo!() +} + +#[uucore::main] +pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let args = uu_app().try_get_matches_from_mut(args)?; + + if args.contains_id(options::ENABLE) { + let cpu_list = args + .get_one::(options::ENABLE) + .expect("cpu-list is required"); + + enable_cpu_list(cpu_list) + } else if args.contains_id(options::DISABLE) { + let cpu_list = args + .get_one::(options::DISABLE) + .expect("cpu-list is required"); + + disable_cpu_list(cpu_list) + } else if args.contains_id(options::CONFIGURE) { + let cpu_list = args + .get_one::(options::CONFIGURE) + .expect("cpu-list is required"); + + configure_cpu_list(cpu_list) + } else if args.contains_id(options::DECONFIGURE) { + let cpu_list = args + .get_one::(options::DECONFIGURE) + .expect("cpu-list is required"); + + deconfigure_cpu_list(cpu_list) + } else if args.contains_id(options::DISPATCH) { + let dispatch_mode = args + .get_one::(options::DISPATCH) + .expect("mode is required"); + + set_dispatch_mode(*dispatch_mode) + } else if args.get_flag(options::RESCAN) { + rescan_cpus() + } else { + unimplemented!(); + } +} + +pub fn uu_app() -> Command { + Command::new(uucore::util_name()) + .version(crate_version!()) + .about(ABOUT) + .override_usage(format_usage(USAGE)) + .infer_long_args(true) + .arg_required_else_help(true) + .arg( + Arg::new(options::ENABLE) + .short('e') + .long(options::ENABLE) + .value_name(options::CPU_LIST) + .value_parser(CpuList::from_str) + .action(ArgAction::Set) + .help("enable CPUs"), + ) + .arg( + Arg::new(options::DISABLE) + .short('d') + .long(options::DISABLE) + .value_name(options::CPU_LIST) + .value_parser(CpuList::from_str) + .action(ArgAction::Set) + .help("disable CPUs"), + ) + .arg( + Arg::new(options::CONFIGURE) + .short('c') + .long(options::CONFIGURE) + .value_name(options::CPU_LIST) + .value_parser(CpuList::from_str) + .action(ArgAction::Set) + .help("configure CPUs"), + ) + .arg( + Arg::new(options::DECONFIGURE) + .short('g') + .long(options::DECONFIGURE) + .value_name(options::CPU_LIST) + .value_parser(CpuList::from_str) + .action(ArgAction::Set) + .help("deconfigure CPUs"), + ) + .arg( + Arg::new(options::DISPATCH) + .short('p') + .long(options::DISPATCH) + .value_name(options::MODE) + .value_parser(EnumValueParser::::new()) + .action(ArgAction::Set) + .help("set dispatching mode"), + ) + .arg( + Arg::new(options::RESCAN) + .short('r') + .long(options::RESCAN) + .action(ArgAction::SetTrue) + .help("trigger rescan of CPUs"), + ) + .group( + ArgGroup::new("control-group") + .args([ + options::ENABLE, + options::DISABLE, + options::CONFIGURE, + options::DECONFIGURE, + ]) + .multiple(false) + .conflicts_with_all(["dispatch-group", "rescan-group"]), + ) + .group( + ArgGroup::new("dispatch-group") + .args([options::DISPATCH]) + .multiple(false) + .conflicts_with_all(["control-group", "rescan-group"]), + ) + .group( + ArgGroup::new("rescan-group") + .args([options::RESCAN]) + .multiple(false) + .conflicts_with_all(["control-group", "dispatch-group"]), + ) + .after_help( + " is one or more elements separated by commas. \ + Each element is either a positive integer (e.g., 3), \ + or an inclusive range of positive integers (e.g., 0-5). \ + For example, 0,2,7,10-13 refers to CPUs whose addresses are: 0, 2, 7, 10, 11, 12, and 13.", + ) +} diff --git a/src/uu/chcpu/src/errors.rs b/src/uu/chcpu/src/errors.rs new file mode 100644 index 0000000..c3a8fdf --- /dev/null +++ b/src/uu/chcpu/src/errors.rs @@ -0,0 +1,44 @@ +// This file is part of the uutils hostname package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use std::fmt; + +use uucore::error::UError; + +#[derive(Debug, PartialEq, Eq)] +pub enum ChCpuError { + EmptyCpuList, + CpuSpecNotPositiveInteger, + CpuSpecFirstAfterLast, +} + +impl fmt::Display for ChCpuError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::EmptyCpuList => write!(f, "CPU list is empty"), + Self::CpuSpecNotPositiveInteger => { + write!(f, "CPU list element is not a positive number") + } + Self::CpuSpecFirstAfterLast => { + write!( + f, + "first element of CPU list range is greater than its last element" + ) + } + } + } +} + +impl UError for ChCpuError { + fn code(&self) -> i32 { + 1 + } + + fn usage(&self) -> bool { + false + } +} + +impl std::error::Error for ChCpuError {} diff --git a/src/uu/chcpu/src/main.rs b/src/uu/chcpu/src/main.rs new file mode 100644 index 0000000..fe72ddc --- /dev/null +++ b/src/uu/chcpu/src/main.rs @@ -0,0 +1 @@ +uucore::bin!(uu_chcpu);