Improve reading sections in
This commit is contained in:
parent
d92c2f5a56
commit
024e4145e0
|
@ -7,4 +7,5 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
clap = {version = "*", features = ["derive"]}
|
||||
num-traits = "*"
|
||||
tool_helper = {path = "../tool_helper"}
|
|
@ -5,49 +5,63 @@ use std::io::BufRead;
|
|||
use types::{Section};
|
||||
|
||||
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"))
|
||||
}
|
||||
|
||||
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() {
|
||||
if line.starts_with(".") {
|
||||
process_section(line, &mut line_iter);
|
||||
process_section(line, &mut line_iter)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
macro_rules! force_next {
|
||||
($split_line:ident, $line_iter:ident, $line:ident) => {
|
||||
{
|
||||
if let Some(value) = $split_line.next() {
|
||||
value
|
||||
}
|
||||
|
||||
else {
|
||||
$line = $line_iter.next().unwrap();
|
||||
$split_line = $line.split_whitespace();
|
||||
|
||||
$split_line.next().unwrap()
|
||||
}
|
||||
}
|
||||
};
|
||||
fn process_section<F: std::iter::Iterator<Item=String>>(line: String, line_iter:&mut F) -> Result<(), Error> {
|
||||
let (section, _line) = read_section(line, || {
|
||||
line_iter.next().ok_or(Error::from_str(""))
|
||||
})?;
|
||||
|
||||
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 name = split_line.next().unwrap().to_string();
|
||||
let adr = u64::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok();
|
||||
let size = { // If adr is already empty we do not need to check for a size
|
||||
if adr.is_some() {
|
||||
usize::from_str_radix(force_next!(split_line, line_iter, line).trim_start_matches("0x"), 16).ok()
|
||||
}
|
||||
let name = split_line.next().ok_or(Error::from_str(""))?.to_string();
|
||||
let need_new_line = name.chars().count() > 16;
|
||||
|
||||
else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if need_new_line {
|
||||
line = next_line()?;
|
||||
split_line = line.split_whitespace();
|
||||
}
|
||||
|
||||
println!("Section: {} @{:?} {:?}", name, adr, size);
|
||||
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 {
|
||||
None
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue