mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-09 23:08:18 +02:00
kraid/isa: Add a simple XML parser
The xml crate doesn't provide a DOM but it makes everything easier to have one so let's hand-roll a super simple DOM for the ISA XML. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41841>
This commit is contained in:
parent
99dd4d269f
commit
052a758cfb
2 changed files with 103 additions and 1 deletions
|
|
@ -2,10 +2,12 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pub mod encoder;
|
||||
mod xml;
|
||||
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::ToTokens;
|
||||
use std::ops::Range;
|
||||
use xml::XmlElement;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ident {
|
||||
|
|
@ -163,7 +165,13 @@ pub struct ISA {
|
|||
}
|
||||
|
||||
impl ISA {
|
||||
pub fn from_xml_file(file: std::fs::File, arch: Range<u8>) -> Result<ISA> {
|
||||
fn from_xml(xml: XmlElement, arch: Range<u8>) -> Result<ISA> {
|
||||
assert_eq!(xml.name.local_name, "mali-isa");
|
||||
|
||||
Ok(ISA { arch })
|
||||
}
|
||||
|
||||
pub fn from_xml_file(file: std::fs::File, arch: Range<u8>) -> Result<ISA> {
|
||||
ISA::from_xml(xml::XmlElement::from_xml_file(file)?, arch)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
94
src/panfrost/compiler/kraid/proc/isa/xml.rs
Normal file
94
src/panfrost/compiler/kraid/proc/isa/xml.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright © 2026 Collabora, Ltd.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use xml::attribute::OwnedAttribute;
|
||||
use xml::name::OwnedName;
|
||||
use xml::reader::{EventReader, XmlEvent};
|
||||
|
||||
/// A very simpl DOM
|
||||
pub struct XmlElement {
|
||||
pub name: OwnedName,
|
||||
pub attrs: HashMap<String, String>,
|
||||
pub children: Vec<XmlElement>,
|
||||
}
|
||||
|
||||
impl XmlElement {
|
||||
fn from_xml_event(
|
||||
name: OwnedName,
|
||||
attributes: Vec<OwnedAttribute>,
|
||||
events: &mut impl Iterator<Item = xml::reader::Result<XmlEvent>>,
|
||||
) -> xml::reader::Result<XmlElement> {
|
||||
let mut elem = XmlElement {
|
||||
name,
|
||||
attrs: attributes
|
||||
.into_iter()
|
||||
.map(|a| (a.name.local_name, a.value))
|
||||
.collect(),
|
||||
children: Default::default(),
|
||||
};
|
||||
|
||||
while let Some(event) = events.next() {
|
||||
match event? {
|
||||
XmlEvent::StartElement {
|
||||
name, attributes, ..
|
||||
} => {
|
||||
elem.children.push(XmlElement::from_xml_event(
|
||||
name, attributes, events,
|
||||
)?);
|
||||
}
|
||||
XmlEvent::EndElement { .. } => return Ok(elem),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
Err(xml::reader::ErrorKind::UnexpectedEof.into())
|
||||
}
|
||||
|
||||
pub fn from_xml_file(
|
||||
file: std::fs::File,
|
||||
) -> xml::reader::Result<XmlElement> {
|
||||
// Buffering is important for performance
|
||||
let file = std::io::BufReader::new(file);
|
||||
let mut events = EventReader::new(file).into_iter();
|
||||
|
||||
while let Some(event) = events.next() {
|
||||
match event? {
|
||||
XmlEvent::StartElement {
|
||||
name, attributes, ..
|
||||
} => {
|
||||
return XmlElement::from_xml_event(
|
||||
name,
|
||||
attributes,
|
||||
&mut events,
|
||||
)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
Err(xml::reader::ErrorKind::UnexpectedEof.into())
|
||||
}
|
||||
|
||||
pub fn get_u8_attr(&self, name: &str) -> Option<u8> {
|
||||
let s = self.attrs.get(name)?;
|
||||
let u = u8::from_str_radix(s, 10).unwrap();
|
||||
Some(u)
|
||||
}
|
||||
|
||||
pub fn get_bool_attr(&self, name: &str) -> Option<bool> {
|
||||
self.get_u8_attr(name).map(|u| u != 0)
|
||||
}
|
||||
|
||||
pub fn get_arch(&self, all_arch: Range<u8>) -> Range<u8> {
|
||||
let mut range = all_arch;
|
||||
if let Some(since) = self.get_u8_attr("since") {
|
||||
range.start = range.start.max(since);
|
||||
}
|
||||
if let Some(until) = self.get_u8_attr("until") {
|
||||
range.end = range.end.min(until + 1);
|
||||
}
|
||||
range
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue