Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
298
third-party/vendor/wayland-scanner/src/parse.rs
vendored
Normal file
298
third-party/vendor/wayland-scanner/src/parse.rs
vendored
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
use crate::protocol::*;
|
||||
use std::io::Read;
|
||||
use xml::attribute::OwnedAttribute;
|
||||
use xml::reader::ParserConfig;
|
||||
use xml::reader::XmlEvent;
|
||||
use xml::EventReader;
|
||||
|
||||
macro_rules! extract_from(
|
||||
($it: expr => $pattern: pat => $result: expr) => (
|
||||
match $it.next() {
|
||||
Ok($pattern) => { $result },
|
||||
e => panic!("Ill-formed protocol file: {:?}", e)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! extract_end_tag(
|
||||
($it: expr => $tag: expr) => (
|
||||
extract_from!($it => XmlEvent::EndElement { name } => {
|
||||
assert!(name.local_name == $tag, "Ill-formed protocol file");
|
||||
});
|
||||
)
|
||||
);
|
||||
|
||||
pub fn parse_stream<S: Read>(stream: S) -> Protocol {
|
||||
let mut reader =
|
||||
EventReader::new_with_config(stream, ParserConfig::new().trim_whitespace(true));
|
||||
reader.next().expect("Could not read from event reader");
|
||||
parse_protocol(reader)
|
||||
}
|
||||
|
||||
fn parse_protocol<R: Read>(mut reader: EventReader<R>) -> Protocol {
|
||||
let mut protocol = extract_from!(
|
||||
reader => XmlEvent::StartElement { name, attributes, .. } => {
|
||||
assert!(name.local_name == "protocol", "Missing protocol toplevel tag");
|
||||
assert!(attributes[0].name.local_name == "name", "Protocol must have a name");
|
||||
Protocol::new(attributes[0].value.clone())
|
||||
}
|
||||
);
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => {
|
||||
match &name.local_name[..] {
|
||||
"copyright" => {
|
||||
// parse the copyright
|
||||
let copyright = match reader.next() {
|
||||
Ok(XmlEvent::Characters(copyright))
|
||||
| Ok(XmlEvent::CData(copyright)) => copyright,
|
||||
e => panic!("Ill-formed protocol file: {:?}", e),
|
||||
};
|
||||
|
||||
extract_end_tag!(reader => "copyright");
|
||||
protocol.copyright = Some(copyright);
|
||||
}
|
||||
"interface" => {
|
||||
protocol.interfaces.push(parse_interface(&mut reader, attributes));
|
||||
}
|
||||
"description" => {
|
||||
protocol.description = Some(parse_description(&mut reader, attributes));
|
||||
}
|
||||
_ => panic!(
|
||||
"Ill-formed protocol file: unexpected token `{}` in protocol {}",
|
||||
name.local_name, protocol.name
|
||||
),
|
||||
}
|
||||
}
|
||||
Ok(XmlEvent::EndElement { name }) => {
|
||||
assert!(
|
||||
name.local_name == "protocol",
|
||||
"Unexpected closing token `{}`",
|
||||
name.local_name
|
||||
);
|
||||
break;
|
||||
}
|
||||
e => panic!("Ill-formed protocol file: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
protocol
|
||||
}
|
||||
|
||||
fn parse_interface<R: Read>(reader: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Interface {
|
||||
let mut interface = Interface::new();
|
||||
for attr in attrs {
|
||||
match &attr.name.local_name[..] {
|
||||
"name" => interface.name = attr.value,
|
||||
"version" => interface.version = attr.value.parse().unwrap(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => match &name.local_name[..] {
|
||||
"description" => {
|
||||
interface.description = Some(parse_description(reader, attributes))
|
||||
}
|
||||
"request" => interface.requests.push(parse_request(reader, attributes)),
|
||||
"event" => interface.events.push(parse_event(reader, attributes)),
|
||||
"enum" => interface.enums.push(parse_enum(reader, attributes)),
|
||||
_ => panic!("Unexpected tocken: `{}`", name.local_name),
|
||||
},
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "interface" => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
interface
|
||||
}
|
||||
|
||||
fn parse_description<R: Read>(
|
||||
reader: &mut EventReader<R>,
|
||||
attrs: Vec<OwnedAttribute>,
|
||||
) -> (String, String) {
|
||||
let mut summary = String::new();
|
||||
for attr in attrs {
|
||||
if &attr.name.local_name[..] == "summary" {
|
||||
summary = attr.value.split_whitespace().collect::<Vec<_>>().join(" ");
|
||||
}
|
||||
}
|
||||
|
||||
let description = match reader.next() {
|
||||
Ok(XmlEvent::Characters(txt)) => {
|
||||
extract_end_tag!(reader => "description");
|
||||
txt
|
||||
}
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "description" => String::new(),
|
||||
e => panic!("Ill-formed protocol file: {:?}", e),
|
||||
};
|
||||
|
||||
(summary, description)
|
||||
}
|
||||
|
||||
fn parse_request<R: Read>(reader: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Message {
|
||||
let mut request = Message::new();
|
||||
for attr in attrs {
|
||||
match &attr.name.local_name[..] {
|
||||
"name" => request.name = attr.value,
|
||||
"type" => request.typ = Some(parse_type(&attr.value)),
|
||||
"since" => request.since = attr.value.parse().unwrap(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => match &name.local_name[..] {
|
||||
"description" => request.description = Some(parse_description(reader, attributes)),
|
||||
"arg" => request.args.push(parse_arg(reader, attributes)),
|
||||
_ => panic!("Unexpected tocken: `{}`", name.local_name),
|
||||
},
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "request" => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
request
|
||||
}
|
||||
|
||||
fn parse_enum<R: Read>(reader: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Enum {
|
||||
let mut enu = Enum::new();
|
||||
for attr in attrs {
|
||||
match &attr.name.local_name[..] {
|
||||
"name" => enu.name = attr.value,
|
||||
"since" => enu.since = attr.value.parse().unwrap(),
|
||||
"bitfield" => {
|
||||
if &attr.value[..] == "true" {
|
||||
enu.bitfield = true
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => match &name.local_name[..] {
|
||||
"description" => enu.description = Some(parse_description(reader, attributes)),
|
||||
"entry" => enu.entries.push(parse_entry(reader, attributes)),
|
||||
_ => panic!("Unexpected tocken: `{}`", name.local_name),
|
||||
},
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "enum" => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
enu
|
||||
}
|
||||
|
||||
fn parse_event<R: Read>(reader: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Message {
|
||||
let mut event = Message::new();
|
||||
for attr in attrs {
|
||||
match &attr.name.local_name[..] {
|
||||
"name" => event.name = attr.value,
|
||||
"type" => event.typ = Some(parse_type(&attr.value)),
|
||||
"since" => event.since = attr.value.parse().unwrap(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => match &name.local_name[..] {
|
||||
"description" => event.description = Some(parse_description(reader, attributes)),
|
||||
"arg" => event.args.push(parse_arg(reader, attributes)),
|
||||
_ => panic!("Unexpected tocken: `{}`", name.local_name),
|
||||
},
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "event" => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
event
|
||||
}
|
||||
|
||||
fn parse_arg<R: Read>(reader: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Arg {
|
||||
let mut arg = Arg::new();
|
||||
for attr in attrs {
|
||||
match &attr.name.local_name[..] {
|
||||
"name" => arg.name = attr.value,
|
||||
"type" => arg.typ = parse_type(&attr.value),
|
||||
"summary" => {
|
||||
arg.summary = Some(attr.value.split_whitespace().collect::<Vec<_>>().join(" "))
|
||||
}
|
||||
"interface" => arg.interface = Some(attr.value),
|
||||
"allow-null" => {
|
||||
if attr.value == "true" {
|
||||
arg.allow_null = true
|
||||
}
|
||||
}
|
||||
"enum" => arg.enum_ = Some(attr.value),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => match &name.local_name[..] {
|
||||
"description" => arg.description = Some(parse_description(reader, attributes)),
|
||||
_ => panic!("Unexpected tocken: `{}`", name.local_name),
|
||||
},
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "arg" => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
arg
|
||||
}
|
||||
|
||||
fn parse_type(txt: &str) -> Type {
|
||||
match txt {
|
||||
"int" => Type::Int,
|
||||
"uint" => Type::Uint,
|
||||
"fixed" => Type::Fixed,
|
||||
"string" => Type::String,
|
||||
"object" => Type::Object,
|
||||
"new_id" => Type::NewId,
|
||||
"array" => Type::Array,
|
||||
"fd" => Type::Fd,
|
||||
"destructor" => Type::Destructor,
|
||||
e => panic!("Unexpected type: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_entry<R: Read>(reader: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) -> Entry {
|
||||
let mut entry = Entry::new();
|
||||
for attr in attrs {
|
||||
match &attr.name.local_name[..] {
|
||||
"name" => entry.name = attr.value,
|
||||
"value" => {
|
||||
entry.value = if attr.value.starts_with("0x") {
|
||||
u32::from_str_radix(&attr.value[2..], 16).unwrap()
|
||||
} else {
|
||||
attr.value.parse().unwrap()
|
||||
};
|
||||
}
|
||||
"since" => entry.since = attr.value.parse().unwrap(),
|
||||
"summary" => {
|
||||
entry.summary = Some(attr.value.split_whitespace().collect::<Vec<_>>().join(" "))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match reader.next() {
|
||||
Ok(XmlEvent::StartElement { name, attributes, .. }) => match &name.local_name[..] {
|
||||
"description" => entry.description = Some(parse_description(reader, attributes)),
|
||||
_ => panic!("Unexpected tocken: `{}`", name.local_name),
|
||||
},
|
||||
Ok(XmlEvent::EndElement { ref name }) if name.local_name == "entry" => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
entry
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue