diff --git a/src/uu/lscpu/src/lscpu.rs b/src/uu/lscpu/src/lscpu.rs index df5195f..310096b 100644 --- a/src/uu/lscpu/src/lscpu.rs +++ b/src/uu/lscpu/src/lscpu.rs @@ -11,6 +11,7 @@ use sysfs::CacheSize; use uucore::{error::UResult, format_usage, help_about, help_usage}; mod options { + pub const BYTES: &str = "bytes"; pub const HEX: &str = "hex"; pub const JSON: &str = "json"; } @@ -64,6 +65,7 @@ impl CpuInfos { } struct OutputOptions { + bytes: bool, json: bool, _hex: bool, } @@ -73,6 +75,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; let output_opts = OutputOptions { + bytes: matches.get_flag(options::BYTES), _hex: matches.get_flag(options::HEX), json: matches.get_flag(options::JSON), }; @@ -151,7 +154,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { cpu_infos.push(vendor_info); } - if let Some(cache_info) = calculate_cache_totals(cpu_topology.cpus) { + if let Some(cache_info) = calculate_cache_totals(cpu_topology.cpus, &output_opts) { cpu_infos.push(cache_info); } @@ -169,7 +172,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(()) } -fn calculate_cache_totals(cpus: Vec<sysfs::Cpu>) -> Option<CpuInfo> { +fn calculate_cache_totals(cpus: Vec<sysfs::Cpu>, out_opts: &OutputOptions) -> Option<CpuInfo> { let mut by_levels: HashMap<String, Vec<&sysfs::CpuCache>> = HashMap::new(); let all_caches: Vec<_> = cpus.iter().flat_map(|cpu| &cpu.caches).collect(); @@ -205,11 +208,16 @@ fn calculate_cache_totals(cpus: Vec<sysfs::Cpu>) -> Option<CpuInfo> { .iter() .fold(0_u64, |acc, c| acc + c.size.size_bytes()); + let size = CacheSize::new(size_total); cache_info.add_child(CpuInfo::new( level, &format!( "{} ({} instances)", - CacheSize::new(size_total).human_readable(), + if out_opts.bytes { + size.raw() + } else { + size.human_readable() + }, count ), )); @@ -331,4 +339,15 @@ pub fn uu_app() -> Command { ) .action(ArgAction::SetTrue), ) + .arg( + Arg::new(options::BYTES) + .short('B') + .long("bytes") + .action(ArgAction::SetTrue) + .help( + "Print the sizes in bytes rather than in a human-readable format. \ + The default is to print sizes in human-readable format (for example '512 KiB'). \ + Setting this flag instead prints the decimal amount of bytes with no suffix.", + ), + ) } diff --git a/src/uu/lscpu/src/sysfs.rs b/src/uu/lscpu/src/sysfs.rs index bbbf9d7..d1cbafb 100644 --- a/src/uu/lscpu/src/sysfs.rs +++ b/src/uu/lscpu/src/sysfs.rs @@ -118,6 +118,10 @@ impl CacheSize { self.0 } + pub fn raw(&self) -> String { + format!("{}", self.0) + } + pub fn human_readable(&self) -> String { let (unit, denominator) = match self.0 { x if x < 1024_u64.pow(1) => ("B", 1024_u64.pow(0)), @@ -278,6 +282,10 @@ fn test_print_cache_size() { assert_eq!(CacheSize::new(1024 * 1024).human_readable(), "1 MiB"); assert_eq!(CacheSize::new(1024 * 1024 * 1024).human_readable(), "1 GiB"); + assert_eq!(CacheSize::new(1023).raw(), "1023"); + assert_eq!(CacheSize::new(1024 * 1024).raw(), "1048576"); + assert_eq!(CacheSize::new(1024 * 1024 * 1024).raw(), "1073741824"); + assert_eq!(CacheSize::new(3 * 1024).human_readable(), "3 KiB"); assert_eq!( CacheSize::new((7.6 * 1024.0 * 1024.0) as u64).human_readable(),