diff --git a/src/uu/dmesg/src/dmesg.rs b/src/uu/dmesg/src/dmesg.rs index 1298d09..1343bbc 100644 --- a/src/uu/dmesg/src/dmesg.rs +++ b/src/uu/dmesg/src/dmesg.rs @@ -154,8 +154,12 @@ impl Dmesg<'_> { fn print_normal(&self) { if let Some(records) = &self.records { let mut reltime_formatter = time_formatter::ReltimeFormatter::new(); + let mut delta_formatter = time_formatter::DeltaFormatter::new(); for record in records { match self.time_format { + TimeFormat::Delta => { + print!("[{}] ", delta_formatter.format(record.timestamp_us as i64)) + } TimeFormat::Reltime => { print!( "[{}] ", @@ -172,7 +176,6 @@ impl Dmesg<'_> { print!("[{}] ", time_formatter::raw(record.timestamp_us)) } TimeFormat::Notime => (), - _ => unimplemented!(), } println!("{}", record.message); } diff --git a/src/uu/dmesg/src/time_formatter.rs b/src/uu/dmesg/src/time_formatter.rs index 26b4833..4f21ab5 100644 --- a/src/uu/dmesg/src/time_formatter.rs +++ b/src/uu/dmesg/src/time_formatter.rs @@ -29,6 +29,11 @@ pub struct ReltimeFormatter { previous_unix_timestamp: i64, } +pub struct DeltaFormatter { + state: State, + prev_timestamp_us: i64, +} + pub enum State { Initial, AfterBoot, @@ -77,6 +82,39 @@ impl ReltimeFormatter { } } +impl DeltaFormatter { + pub fn new() -> Self { + DeltaFormatter { + state: State::Initial, + prev_timestamp_us: 0, + } + } + + pub fn format(&mut self, timestamp_us: i64) -> String { + let format_res = match self.state { + State::Delta => Self::delta(timestamp_us - self.prev_timestamp_us), + _ => Self::delta(0), + }; + self.prev_timestamp_us = timestamp_us; + self.state = match self.state { + State::Initial if timestamp_us == 0 => State::AfterBoot, + _ => State::Delta, + }; + format_res + } + + fn delta(delta_us: i64) -> String { + let seconds = i64::abs(delta_us / 1000000); + let sub_seconds = i64::abs(delta_us % 1000000); + let sign = if delta_us >= 0 { 1.0 } else { -1.0 }; + format!( + "<{:>5.0}.{:0>6}>", + sign * f64::from(seconds as i32), + sub_seconds + ) + } +} + static BOOT_TIME: OnceLock<DateTime<FixedOffset>> = OnceLock::new(); #[cfg(feature = "fixed-boot-time")]