Skip to content

Commit

Permalink
Parse <feature>
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmusgo committed Apr 23, 2024
1 parent 8c7bb16 commit ed06c3e
Showing 1 changed file with 122 additions and 0 deletions.
122 changes: 122 additions & 0 deletions generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ impl Parser {
"commands" => {
self.parse_commands();
}
"feature" => {
self.parse_feature();
}
"extensions" => {
self.parse_extensions();
}
Expand Down Expand Up @@ -162,6 +165,125 @@ impl Parser {
}
}

fn parse_feature(&mut self) {
loop {
use XmlEvent::*;
match self.reader.next().expect("failed to parse XML") {
StartElement { name, .. } => match &name.local_name[..] {
"require" => {
self.parse_feature_required();
}
_ => {
eprintln!("unimplemented feature element: {}", name.local_name);
self.finish_element();
}
},
EndElement { name } => {
if name.local_name == "feature" {
break;
}
eprintln!("unexpected end element: {}", name);
}
EndDocument => {
panic!("unexpected end of document");
}
_ => {}
}
}
}

fn parse_feature_required(&mut self) {
loop {
use XmlEvent::*;
match self.reader.next().expect("failed to parse XML") {
StartElement {
name, attributes, ..
} => match &name.local_name[..] {
"command" => {
let _name = attr(&attributes, "name").unwrap();
let _comment = attr(&attributes, "comment");
self.finish_element();
}
"enum" => {
let name = attr(&attributes, "name").unwrap();
if let Some(extends) = attr(&attributes, "extends") {
const EXT_BASE: i32 = 1_000_000_000;
const EXT_BLOCK_SIZE: i32 = 1000;
let ext_number = attr(&attributes, "extnumber")
.unwrap()
.parse::<i32>()
.unwrap();

let value = if let Some(offset) = attr(&attributes, "offset") {
let offset = offset.parse::<i32>().unwrap();
let sign = if attr(&attributes, "dir").map_or(false, |x| x == "-") {
-1
} else {
1
};
ConstantValue::Literal(
sign * (EXT_BASE + (ext_number - 1) * EXT_BLOCK_SIZE + offset),
)
} else if let Some(bitpos) = attr(&attributes, "bitpos") {
ConstantValue::Literal(bitpos.parse::<i32>().unwrap())
} else {
ConstantValue::Alias(attr(&attributes, "alias").unwrap().into())
};
let bitmasks = &mut self.bitmasks;
if let Some(e) = self.enums.get_mut(extends) {
e.values.push(Constant {
name: name.into(),
value,
comment: attr(&attributes, "comment").and_then(tidy_comment),
});
} else if let Some(e) = self
.bitvalues
.get(extends)
.and_then(|x| bitmasks.get_mut(x))
{
e.values.push(Constant {
name: name.into(),
value: match value {
ConstantValue::Literal(x) => {
ConstantValue::Literal(x as u64)
}
ConstantValue::Alias(x) => ConstantValue::Alias(x),
},
comment: attr(&attributes, "comment").and_then(tidy_comment),
});
} else {
eprintln!("extension to unrecognized type {}", extends);
}
} else if let Some(alias) = attr(&attributes, "alias") {
self.api_aliases.push((name.into(), alias.into()));
} else if let Some(value) = attr(&attributes, "value") {
self.api_constants
.push((name.into(), value.parse().unwrap()));
}
self.finish_element();
}
"type" => {
self.parse_type(&attributes);
}
_ => {
eprintln!("unimplemented feature require element: {}", name.local_name);
self.finish_element();
}
},
EndElement { name } => {
if name.local_name == "require" {
break;
}
eprintln!("unexpected end element: {}", name);
}
EndDocument => {
panic!("unexpected end of document");
}
_ => {}
}
}
}

fn parse_extensions(&mut self) {
loop {
use XmlEvent::*;
Expand Down

0 comments on commit ed06c3e

Please sign in to comment.