Improve reading sections in

This commit is contained in:
jaby 2023-06-29 21:32:49 +02:00
parent ef233d5d07
commit a77c8aae8d
2 changed files with 45 additions and 30 deletions

View File

@ -7,4 +7,5 @@ edition = "2021"
[dependencies] [dependencies]
clap = {version = "*", features = ["derive"]} clap = {version = "*", features = ["derive"]}
num-traits = "*"
tool_helper = {path = "../tool_helper"} tool_helper = {path = "../tool_helper"}

View File

@ -5,49 +5,63 @@ use std::io::BufRead;
use types::{Section}; use types::{Section};
pub fn scan(input: Input) -> Result<Vec<Section>, Error> { pub fn scan(input: Input) -> Result<Vec<Section>, Error> {
process(input.lines().map(|l| l.unwrap()).into_iter()); process(input.lines().map(|l| l.unwrap()).into_iter())?;
Err(Error::not_implemented("readmap::scan")) Err(Error::not_implemented("readmap::scan"))
} }
fn process<F: std::iter::Iterator<Item=String>>(mut line_iter:F) { fn process<F: std::iter::Iterator<Item=String>>(mut line_iter:F) -> Result<(), Error> {
while let Some(line) = line_iter.next() { while let Some(line) = line_iter.next() {
if line.starts_with(".") { if line.starts_with(".") {
process_section(line, &mut line_iter); process_section(line, &mut line_iter)?;
}
} }
} }
macro_rules! force_next { Ok(())
($split_line:ident, $line_iter:ident, $line:ident) => {
{
if let Some(value) = $split_line.next() {
value
} }
else { fn process_section<F: std::iter::Iterator<Item=String>>(line: String, line_iter:&mut F) -> Result<(), Error> {
$line = $line_iter.next().unwrap(); let (section, _line) = read_section(line, || {
$split_line = $line.split_whitespace(); line_iter.next().ok_or(Error::from_str(""))
})?;
$split_line.next().unwrap() println!("Section: {} @{:?} {:?}", section.name, section.adr, section.size);
} Ok(())
}
};
} }
fn process_section<F: std::iter::Iterator<Item=String>>(mut line: String, line_iter:&mut F) { fn read_section<F:FnMut()-> Result<String, Error>>(mut line: String, mut next_line: F) -> Result<(Section, Option<String>), Error> {
let mut split_line = line.split_whitespace(); let mut split_line = line.split_whitespace();
let name = split_line.next().unwrap().to_string(); let name = split_line.next().ok_or(Error::from_str(""))?.to_string();
let adr = u64::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok(); let need_new_line = name.chars().count() > 16;
let size = { // If adr is already empty we do not need to check for a size
if adr.is_some() { if need_new_line {
usize::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok() line = next_line()?;
split_line = line.split_whitespace();
}
let adr = read_as::<u64>(split_line.next());
if adr.is_none() {
return Ok((Section::new(name, None, None), {
if need_new_line {
Some(line)
}
else {
None
}
}));
}
let size = read_as::<usize>(split_line.next());
Ok((Section::new(name, adr, size), None))
}
fn read_as<F: num_traits::Num>(str: Option<&str>) -> Option<F> {
if let Some(str) = str {
F::from_str_radix(str.trim_start_matches("0x"), 16).ok()
} }
else { else {
None None
} }
};
println!("Section: {} @{:?} {:?}", name, adr, size);
} }