From 1fc7814bee5d90f83bab428c8167af43201f8a9b Mon Sep 17 00:00:00 2001 From: Leyman <82012937+lmaxyz@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:14:40 +0300 Subject: [PATCH] Headerless xml parsing fix (#715) * Add tests for parsing * Fix headerless xml parsing * Add comment * Enable some protocols disabled before * Remove useless body from tested xml file * Fix code formatting * Add changelogs --------- Co-authored-by: Leyman Max <jiumoh2011@yandex.ru> --- wayland-protocols-plasma/CHANGELOG.md | 2 + wayland-protocols-plasma/src/lib.rs | 28 +++++----- wayland-scanner/CHANGELOG.md | 1 + wayland-scanner/src/parse.rs | 53 +++++++++++++++---- .../test-headerless-protocol.xml | 2 + 5 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 wayland-scanner/tests/scanner_assets/test-headerless-protocol.xml diff --git a/wayland-protocols-plasma/CHANGELOG.md b/wayland-protocols-plasma/CHANGELOG.md index 8187ea5d518..b086c493c1c 100644 --- a/wayland-protocols-plasma/CHANGELOG.md +++ b/wayland-protocols-plasma/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Make available protocols that based on headerless xml files. + ## 0.2.0 -- 2023-09-02 ### Breaking changes diff --git a/wayland-protocols-plasma/src/lib.rs b/wayland-protocols-plasma/src/lib.rs index 52823ec5ecc..1553f62268c 100644 --- a/wayland-protocols-plasma/src/lib.rs +++ b/wayland-protocols-plasma/src/lib.rs @@ -49,14 +49,12 @@ pub mod fake_input { ); } -// This protocol is disabled for now as the file is not valid XML because it does not have a XML header -// -// pub mod fullscreen_shell { -// wayland_protocol!( -// "./plasma-wayland-protocols/src/protocols/fullscreen-shell.xml", -// [] -// ); -// } +pub mod fullscreen_shell { + wayland_protocol!( + "./plasma-wayland-protocols/src/protocols/fullscreen-shell.xml", + [] + ); +} pub mod idle { wayland_protocol!( @@ -179,14 +177,12 @@ pub mod slide { ); } -// This protocol is disabled for now as the file is not valid XML because it does not have a XML header -// -// pub mod surface_extension { -// wayland_protocol!( -// "./plasma-wayland-protocols/src/protocols/surface-extension.xml", -// [] -// ); -// } +pub mod surface_extension { + wayland_protocol!( + "./plasma-wayland-protocols/src/protocols/surface-extension.xml", + [] + ); +} pub mod text_input { pub mod v1 { diff --git a/wayland-scanner/CHANGELOG.md b/wayland-scanner/CHANGELOG.md index 1b8ea54b10d..bb378accb7f 100644 --- a/wayland-scanner/CHANGELOG.md +++ b/wayland-scanner/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Use wrapper type implementing `Sync` instead of `static mut`s. +- Add headerless xml file parsing possibility for `parse` function. ## 0.31.1 -- 2024-01-29 diff --git a/wayland-scanner/src/parse.rs b/wayland-scanner/src/parse.rs index b07c6531ccf..73aafde625c 100644 --- a/wayland-scanner/src/parse.rs +++ b/wayland-scanner/src/parse.rs @@ -29,8 +29,6 @@ macro_rules! extract_end_tag( pub fn parse<S: Read>(stream: S) -> Protocol { let mut reader = Reader::from_reader(BufReader::new(stream)); reader.trim_text(true).expand_empty_elements(true); - // Skip first <?xml ... ?> event - let _ = reader.read_event_into(&mut Vec::new()); parse_protocol(reader) } @@ -52,17 +50,33 @@ fn parse_or_panic<T: FromStr>(txt: &[u8]) -> T { } } -fn parse_protocol<R: BufRead>(mut reader: Reader<R>) -> Protocol { - let mut protocol = extract_from!( - reader => Event::Start(bytes) => { - assert!(bytes.name().into_inner() == b"protocol", "Missing protocol toplevel tag"); - if let Some(attr) = bytes.attributes().filter_map(|res| res.ok()).find(|attr| attr.key.into_inner() == b"name") { - Protocol::new(decode_utf8_or_panic(attr.value.into_owned())) - } else { - panic!("Protocol must have a name"); +fn init_protocol<R: BufRead>(reader: &mut Reader<R>) -> Protocol { + // Check two firsts lines for protocol tag + for _ in 0..2 { + match reader.read_event_into(&mut Vec::new()) { + Ok(Event::Decl(_)) => { + continue; + } + Ok(Event::Start(bytes)) => { + assert!(bytes.name().into_inner() == b"protocol", "Missing protocol toplevel tag"); + if let Some(attr) = bytes + .attributes() + .filter_map(|res| res.ok()) + .find(|attr| attr.key.into_inner() == b"name") + { + return Protocol::new(decode_utf8_or_panic(attr.value.into_owned())); + } else { + panic!("Protocol must have a name"); + } } + _ => panic!("Ill-formed protocol file"), } - ); + } + panic!("Ill-formed protocol file"); +} + +fn parse_protocol<R: BufRead>(mut reader: Reader<R>) -> Protocol { + let mut protocol = init_protocol(&mut reader); loop { match reader.read_event_into(&mut Vec::new()) { @@ -366,3 +380,20 @@ fn parse_entry<R: BufRead>(reader: &mut Reader<R>, attrs: Attributes) -> Entry { entry } + +#[cfg(test)] +mod tests { + #[test] + fn xml_parse() { + let protocol_file = + std::fs::File::open("./tests/scanner_assets/test-protocol.xml").unwrap(); + let _ = crate::parse::parse(protocol_file); + } + + #[test] + fn headerless_xml_parse() { + let protocol_file = + std::fs::File::open("./tests/scanner_assets/test-headerless-protocol.xml").unwrap(); + let _ = crate::parse::parse(protocol_file); + } +} diff --git a/wayland-scanner/tests/scanner_assets/test-headerless-protocol.xml b/wayland-scanner/tests/scanner_assets/test-headerless-protocol.xml new file mode 100644 index 00000000000..824ebc6e32d --- /dev/null +++ b/wayland-scanner/tests/scanner_assets/test-headerless-protocol.xml @@ -0,0 +1,2 @@ +<protocol name="test-protocol"> +</protocol> \ No newline at end of file