mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-06-29 16:19:26 +09:00
new: implement converter (Successfully read current CSR XML)
This commit is contained in:
parent
51a074d2c0
commit
53c8cbd90f
5 changed files with 398 additions and 30 deletions
159
src/converter.rs
159
src/converter.rs
|
@ -5,10 +5,10 @@ use std::{num, str};
|
|||
use roxmltree::{Node, TextPos};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::parser::{ParseEnumError, ParsePrefixedU32, ParsePrefixedU32Error};
|
||||
use crate::parser::{ParseCustomBool, ParseEnumError, ParsePrefixedU32, ParsePrefixedU32Error};
|
||||
use crate::types::{
|
||||
BitString, Block, DataType, Field, Fifo, Memory, Module, ModuleBlockElements, MultipleParams,
|
||||
Register, Value,
|
||||
BitString, Block, Field, Fifo, Memory, Module, ModuleBlockElements, MultipleParams, Register,
|
||||
Value,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
|
@ -44,6 +44,11 @@ pub enum DomConversionError {
|
|||
pos: (TextPos, TextPos),
|
||||
found: String,
|
||||
},
|
||||
#[error("failed to complete/infer parameter {param}: {start} - {end}", start = pos.0, end = pos.1)]
|
||||
ParameterCompletion {
|
||||
param: &'static str,
|
||||
pos: (TextPos, TextPos),
|
||||
},
|
||||
#[error("other dom conversion error: {0}")]
|
||||
OtherError(String),
|
||||
}
|
||||
|
@ -88,6 +93,15 @@ impl DomConversionError {
|
|||
}
|
||||
}
|
||||
|
||||
fn parameter_completion_error(param: &'static str, node: Node) -> Self {
|
||||
let range = node.range();
|
||||
let doc = node.document();
|
||||
Self::ParameterCompletion {
|
||||
param,
|
||||
pos: (doc.text_pos_at(range.start), doc.text_pos_at(range.end)),
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid_node(found: String, node: Node) -> Self {
|
||||
let range = node.range();
|
||||
let doc = node.document();
|
||||
|
@ -240,10 +254,7 @@ impl Block {
|
|||
Some(addr) => addr
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "addr", node))?,
|
||||
None => {
|
||||
// derive from parent
|
||||
todo!("need to confirm")
|
||||
}
|
||||
None => 0,
|
||||
};
|
||||
let r#type = match util::get_type(node).transpose()? {
|
||||
Some(x) => Some(x),
|
||||
|
@ -305,7 +316,58 @@ impl Block {
|
|||
|
||||
impl Register {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!("do here next")
|
||||
let name = util::get_name(node)?;
|
||||
let addr = match node.attribute("addr") {
|
||||
Some(addr) => addr
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "addr", node))?,
|
||||
None => 0,
|
||||
};
|
||||
let mask = node
|
||||
.attribute("mask")
|
||||
.map(|addr| {
|
||||
addr.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "mask", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let modf = util::get_modf(node)
|
||||
.transpose()?
|
||||
.map_or_else(
|
||||
|| {
|
||||
node.ancestors()
|
||||
.filter_map(util::get_modf)
|
||||
.next()
|
||||
.transpose()
|
||||
},
|
||||
|x| Ok(Some(x)),
|
||||
)?
|
||||
.ok_or_else(|| DomConversionError::parameter_completion_error("modf", node))?;
|
||||
let multiple = MultipleParams::from_xml_dom(node)?;
|
||||
let default = node
|
||||
.attribute("default")
|
||||
.map(|x| {
|
||||
x.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "default", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let desc = node.attribute("desc").map(str::to_string);
|
||||
|
||||
let children = node
|
||||
.children()
|
||||
.filter(|node| node.is_element() && node.tag_name().name().eq("field"))
|
||||
.map(Field::from_xml_dom)
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(Register {
|
||||
name,
|
||||
addr,
|
||||
mask,
|
||||
modf,
|
||||
multiple,
|
||||
default,
|
||||
desc,
|
||||
elements: children,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,13 +385,82 @@ impl Fifo {
|
|||
|
||||
impl Field {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!()
|
||||
let name = util::get_name(node)?;
|
||||
let mask = node
|
||||
.attribute("mask")
|
||||
.map(|addr| {
|
||||
addr.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "mask", node))
|
||||
})
|
||||
.transpose()?
|
||||
.ok_or_else(|| DomConversionError::attr_not_found("mask", node))?;
|
||||
let interface = node
|
||||
.attribute("interface")
|
||||
.map(|s| {
|
||||
s.parse()
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "interface", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let multiple = MultipleParams::from_xml_dom(node)?;
|
||||
let default = node
|
||||
.attribute("default")
|
||||
.map(|x| {
|
||||
x.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "default", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let sclr = node
|
||||
.attribute("sclr")
|
||||
.map(|s| {
|
||||
s.parse_custom_bool()
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "sclr", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let desc = node.attribute("desc").map(str::to_string);
|
||||
|
||||
let children = node
|
||||
.children()
|
||||
.filter(|node| node.is_element())
|
||||
.map(Value::from_xml_dom)
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
if let Some(default) = default {
|
||||
if default & !(mask) != 0 {
|
||||
log::warn!(
|
||||
"default value {} doesn't fit mask {}: {} - {}",
|
||||
default,
|
||||
mask,
|
||||
node.document().text_pos_at(node.range().start),
|
||||
node.document().text_pos_at(node.range().end)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Field {
|
||||
name,
|
||||
mask,
|
||||
interface,
|
||||
multiple,
|
||||
default,
|
||||
sclr,
|
||||
desc,
|
||||
elements: children,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!()
|
||||
let name = util::get_name(node)?;
|
||||
let data = match node.attribute("data") {
|
||||
Some(data) => data
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "data", node))?,
|
||||
None => return Err(DomConversionError::attr_not_found("data", node)),
|
||||
};
|
||||
let desc = node.attribute("desc").map(str::to_string);
|
||||
|
||||
Ok(Value { name, data, desc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,8 +469,8 @@ impl MultipleParams {
|
|||
let multiple = match node
|
||||
.attribute("multiple")
|
||||
.map(|x| {
|
||||
x.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "multiple", node))
|
||||
x.parse()
|
||||
.map_err(|e| DomConversionError::parse_int_error(e, "multiple", node))
|
||||
})
|
||||
.transpose()?
|
||||
{
|
||||
|
@ -350,8 +481,8 @@ impl MultipleParams {
|
|||
let offset = match node
|
||||
.attribute("offset")
|
||||
.map(|x| {
|
||||
x.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "offset", node))
|
||||
x.parse()
|
||||
.map_err(|e| DomConversionError::parse_int_error(e, "offset", node))
|
||||
})
|
||||
.transpose()?
|
||||
{
|
||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -1,26 +1,25 @@
|
|||
use std::fs;
|
||||
|
||||
use anyhow::Result;
|
||||
use endcap_sl_software_ri_generator::types;
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
println!("Hello, world!");
|
||||
let xmlfile = fs::read_to_string("./csr.xml").unwrap();
|
||||
let xmlfile = fs::read_to_string("./csr.xml")?;
|
||||
let doc = roxmltree::Document::parse_with_options(
|
||||
&xmlfile,
|
||||
roxmltree::ParsingOptions {
|
||||
allow_dtd: true,
|
||||
nodes_limit: u32::MAX,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
println!("Parsed: {:#?}", doc);
|
||||
println!("Root: {:?}", doc.root_element());
|
||||
{
|
||||
let root = doc.root_element();
|
||||
println!("tag: {:?}", root.tag_name());
|
||||
let root_childs = root.children().filter(|node| node.is_element());
|
||||
println!("children: {:?}", root_childs);
|
||||
}
|
||||
)?;
|
||||
// println!("Parsed: {:#?}", doc);
|
||||
// println!("Root: {:?}", doc.root_element());
|
||||
|
||||
let register_map = types::Module::from_xml_dom(doc.root_element()).unwrap();
|
||||
let register_map = types::Module::from_xml_dom(doc.root_element())?;
|
||||
println!("read: {:#?}", register_map);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use std::any;
|
||||
|
||||
pub(crate) use parse_custom_bool::ParseCustomBool;
|
||||
pub(crate) use parse_prefixed_u32::ParsePrefixedU32;
|
||||
pub use parse_prefixed_u32::ParsePrefixedU32Error;
|
||||
pub(crate) use parse_custom_bool::ParseCustomBool;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
|
@ -29,7 +29,7 @@ mod parse_prefixed_u32 {
|
|||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum ParsePrefixedU32Error {
|
||||
#[error("invalid prefix: found {found}")]
|
||||
#[error("invalid prefix: found '{found}'")]
|
||||
InvalidPrefix { found: char },
|
||||
#[error("parse int error")]
|
||||
ParseIntError(#[from] num::ParseIntError),
|
||||
|
@ -45,7 +45,7 @@ mod parse_prefixed_u32 {
|
|||
Some('x') => 16,
|
||||
Some(c) if c.is_numeric() => 10,
|
||||
Some(c) => return Err(ParsePrefixedU32Error::InvalidPrefix { found: c }),
|
||||
None => return Err(ParsePrefixedU32Error::InvalidPrefix { found: ' ' }),
|
||||
None => 10,
|
||||
};
|
||||
|
||||
match radix {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue