diff --git a/src/converter.rs b/src/converter.rs index 27d78b0..472ef0f 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -389,11 +389,19 @@ impl Register { .transpose()?; let desc = node.attribute("desc").map(str::to_string); - let children: Vec<_> = node - .children() - .filter(|node| node.is_element() && node.tag_name().name().eq("field")) - .map(Field::from_xml_dom) - .collect::>()?; + let children: Vec<_> = { + let mut child_elements = node.children().filter(|node| node.is_element()); + if child_elements.any(|node| node.tag_name().name().eq("value")) { + // Generate virtual single field under the register, to absorb difference between + // normal format + vec![Field::from_xml_register_dom(node)?] + } else { + child_elements + .filter(|node| node.tag_name().name().eq("field")) + .map(Field::from_xml_dom) + .collect::>()? + } + }; // Validation if default.is_some() && !children.is_empty() { @@ -505,6 +513,45 @@ impl Field { elements: children, }) } + + /// Generate Field from Registers (piracy), guessing a lot of parameters. + pub(crate) fn from_xml_register_dom(node: Node) -> Result { + let name = util::get_name(node)?; + let mask = node + .ancestors() + .filter_map(|node| util::get_type(node)) + .next() + .transpose()? + .map_or_else( + || Err(DomConversionError::parameter_completion_error("type", node)), + |dtype| match dtype { + crate::types::DataType::D32 => Ok(u32::MAX), + }, + )?; + if node.has_attribute("default") { + return Err(DomConversionError::other_error( + "unsupported structure: register with @default without field", + node, + )); + } + let desc = node.attribute("desc").map(str::to_string); + let children = node + .children() + .filter(|node| node.is_element()) + .map(Value::from_xml_dom) + .collect::>()?; + + Ok(Field { + name, + mask, + interface: None, + multiple: None, + default: None, + sclr: None, + desc, + elements: children, + }) + } } impl Value {