Read in map file
This commit is contained in:
parent
eb34dd2e45
commit
26ea6c3838
|
@ -5,16 +5,20 @@ use std::io::BufRead;
|
|||
use types::{Content, Section};
|
||||
|
||||
pub fn scan(input: Input) -> Result<Vec<Section>, Error> {
|
||||
process(input.lines().map(|l| l.unwrap()).into_iter())?;
|
||||
let sections = process(input.lines().map(|l| l.unwrap()).into_iter())?;
|
||||
|
||||
Err(Error::not_implemented("readmap::scan"))
|
||||
Ok(sections)
|
||||
}
|
||||
|
||||
fn process<F: std::iter::Iterator<Item=String>>(mut line_iter:F) -> Result<(), Error> {
|
||||
fn process<F: std::iter::Iterator<Item=String>>(mut line_iter:F) -> Result<Vec<Section>, Error> {
|
||||
let mut sections = Vec::new();
|
||||
while let Some(mut line) = line_iter.next() {
|
||||
loop {
|
||||
if line.starts_with(".") {
|
||||
line = process_section(line, &mut line_iter)?;
|
||||
let (new_line, new_section) = process_section(line, &mut line_iter)?;
|
||||
|
||||
sections.push(new_section);
|
||||
line = new_line;
|
||||
}
|
||||
|
||||
else {
|
||||
|
@ -23,17 +27,16 @@ fn process<F: std::iter::Iterator<Item=String>>(mut line_iter:F) -> Result<(), E
|
|||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(sections)
|
||||
}
|
||||
|
||||
fn process_section<F: std::iter::Iterator<Item=String>>(line: String, line_iter:&mut F) -> Result<String, Error> {
|
||||
fn process_section<F: std::iter::Iterator<Item=String>>(line: String, line_iter:&mut F) -> Result<(String, Section), Error> {
|
||||
let mut next_line_closure = || {
|
||||
line_iter.next().ok_or(Error::from_str("Unexpected end of file"))
|
||||
};
|
||||
let (mut section, line) = read_section(line, &mut next_line_closure)?;
|
||||
|
||||
println!("Section: {} @{:?} {:?} \"{:?}\"", section.name, section.adr, section.size, section.file);
|
||||
process_subsection(&mut section, line, &mut next_line_closure)
|
||||
Ok((process_subsection(&mut section, line, &mut next_line_closure)?, section))
|
||||
}
|
||||
|
||||
fn process_subsection<F:FnMut()-> Result<String, Error>>(section: &mut Section, line: Option<String>, next_line: &mut F) -> Result<String, Error> {
|
||||
|
@ -42,6 +45,18 @@ fn process_subsection<F:FnMut()-> Result<String, Error>>(section: &mut Section,
|
|||
section.content.push(Content::Section(sub_section));
|
||||
}
|
||||
}
|
||||
fn add_element<T>(sub_section: Option<Section>, section: &mut Section, value: T, callback: fn(&mut Section, T)) -> Option<Section> {
|
||||
if let Some(mut sub_section) = sub_section {
|
||||
callback(&mut sub_section, value);
|
||||
Some(sub_section)
|
||||
}
|
||||
|
||||
else {
|
||||
callback(section, value);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mut line = {
|
||||
if let Some(line) = line {
|
||||
line
|
||||
|
@ -69,8 +84,7 @@ fn process_subsection<F:FnMut()-> Result<String, Error>>(section: &mut Section,
|
|||
if line.starts_with(" .") {
|
||||
push_sub_section(section, sub_section);
|
||||
let (section, new_line) = read_section(line, &mut next_line_closure)?;
|
||||
|
||||
println!("\t>>>>> {:?} {:?} {:?} {:?}", section.name, section.adr, section.size, section.file);
|
||||
|
||||
sub_section = Some(section);
|
||||
|
||||
if let Some(new_line) = new_line {
|
||||
|
@ -79,6 +93,20 @@ fn process_subsection<F:FnMut()-> Result<String, Error>>(section: &mut Section,
|
|||
}
|
||||
}
|
||||
|
||||
else if line.starts_with(" *fill*") {
|
||||
let fill = read_fill(line)?;
|
||||
sub_section = add_element(sub_section, section, fill, |section, fill| {
|
||||
section.content.push(Content::Fill(fill));
|
||||
});
|
||||
}
|
||||
|
||||
else if line.starts_with(" 0x") {
|
||||
let symbol = read_symbol(line)?;
|
||||
sub_section = add_element(sub_section, section, symbol, |section, symbol| {
|
||||
section.content.push(Content::Symbol(symbol));
|
||||
});
|
||||
}
|
||||
|
||||
else if line.is_empty() {
|
||||
push_sub_section(section, sub_section);
|
||||
return Ok(line);
|
||||
|
@ -124,6 +152,22 @@ fn read_section<F:FnMut()-> Result<String, Error>>(mut line: String, next_line:
|
|||
Ok((Section::new(name, adr, size, file), None))
|
||||
}
|
||||
|
||||
fn read_fill(line: String) -> Result<types::Fill, Error> {
|
||||
let mut split_line = line.split_whitespace().skip(1);
|
||||
let adr = read_as::<u64>(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires an address")})?;
|
||||
let size = read_as::<usize>(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires a size")})?;
|
||||
|
||||
Ok(types::Fill::new(adr, size))
|
||||
}
|
||||
|
||||
fn read_symbol(line: String) -> Result<types::Symbol, Error> {
|
||||
let mut split_line = line.split_whitespace();
|
||||
let adr = read_as::<u64>(split_line.next()).ok_or_else(|| {return Error::from_str("Symbol statement requires an address")})?;
|
||||
let name = split_line.next().ok_or_else(|| {return Error::from_str("Symbol statement requires a symbol name")})?.to_string();
|
||||
|
||||
Ok(types::Symbol::new(name, adr))
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
|
@ -11,18 +11,18 @@ pub struct Section {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct Symbol {
|
||||
name: String,
|
||||
adr: u64,
|
||||
pub name: String,
|
||||
pub adr: u64,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Fill {
|
||||
adr: u64,
|
||||
size: usize,
|
||||
pub adr: u64,
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
pub enum Content {
|
||||
Fill,
|
||||
Fill(Fill),
|
||||
Section(Section),
|
||||
Symbol(Symbol),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue