dmesg: implement parse function.

This commit is contained in:
Fuad Ismail
2024-11-15 14:56:49 +07:00
parent fa52b0ed62
commit a044bece47
3 changed files with 61 additions and 5 deletions

1
Cargo.lock generated

@ -904,6 +904,7 @@ name = "uu_dmesg"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"clap", "clap",
"regex",
"uucore", "uucore",
] ]

@ -13,3 +13,4 @@ path = "src/main.rs"
[dependencies] [dependencies]
clap = { workspace = true } clap = { workspace = true }
uucore = { workspace = true } uucore = { workspace = true }
regex = { workspace = true }

@ -1,4 +1,6 @@
use clap::{crate_version, Arg, ArgAction, Command}; use clap::{crate_version, Arg, ArgAction, Command};
use regex::Regex;
use std::fs;
use uucore::error::UResult; use uucore::error::UResult;
#[uucore::main] #[uucore::main]
@ -11,7 +13,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
if matches.get_flag(options::JSON) { if matches.get_flag(options::JSON) {
dmesg.output_format = OutputFormat::Json; dmesg.output_format = OutputFormat::Json;
} }
dmesg.parse().print(); dmesg.parse()?.print();
Ok(()) Ok(())
} }
@ -52,13 +54,44 @@ impl Dmesg<'_> {
} }
} }
fn parse(self) -> Self { fn parse(mut self) -> UResult<Self> {
self let mut records = vec![];
let re = Self::record_regex();
let lines = self.read_lines_from_kmsg_file()?;
for line in lines {
for (_, [pri_fac, seq, time, msg]) in re.captures_iter(&line).map(|c| c.extract()) {
records.push(Record::from_str_fields(pri_fac, seq, time, msg.to_string()));
}
}
self._records = Some(records);
Ok(self)
} }
fn print(&self) { fn record_regex() -> Regex {
let valid_number_pattern = "0|[1-9][0-9]*";
let additional_fields_pattern = ",^[,;]*";
let record_pattern = format!(
"(?m)^({0}),({0}),({0}),.(?:{1})*;(.*)$",
valid_number_pattern, additional_fields_pattern
);
Regex::new(&record_pattern).expect("invalid regex.")
} }
fn read_lines_from_kmsg_file(&self) -> UResult<Vec<String>> {
let mut lines = vec![];
let mut line = vec![];
for byte in fs::read(self.kmsg_file)? {
if byte == 0 {
lines.push(String::from_utf8_lossy(&line).to_string());
line.clear();
} else {
line.push(byte);
}
}
Ok(lines)
}
fn print(&self) {}
} }
enum OutputFormat { enum OutputFormat {
@ -67,4 +100,25 @@ enum OutputFormat {
} }
struct Record { struct Record {
_priority_facility: u32,
_sequence: u64,
_timestamp_us: u64,
_message: String,
}
impl Record {
fn from_str_fields(pri_fac: &str, seq: &str, time: &str, msg: String) -> Record {
let pri_fac = str::parse(pri_fac);
let seq = str::parse(seq);
let time = str::parse(time);
match (pri_fac, seq, time) {
(Ok(pri_fac), Ok(seq), Ok(time)) => Record {
_priority_facility: pri_fac,
_sequence: seq,
_timestamp_us: time,
_message: msg,
},
_ => panic!("parse error."),
}
}
} }