gir-format-check-0.1.3/.cargo_vcs_info.json0000644000000001360000000000100141570ustar { "git": { "sha1": "4561415c6789c15b1957224c5ecb1553bc9b269a" }, "path_in_vcs": "" }gir-format-check-0.1.3/.github/workflows/CI.yml000064400000000000000000000016010072674642500174100ustar 00000000000000on: push: branches: [master] pull_request: name: CI jobs: clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - run: rustup component add clippy - run: cargo clippy -- -D warnings check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable override: true components: rustfmt - uses: actions-rs/cargo@v1 name: "Build" with: command: build - uses: actions-rs/cargo@v1 name: "cargo fmt" with: command: fmt args: -- --check - uses: actions-rs/cargo@v1 name: cargo test with: command: test gir-format-check-0.1.3/.gitignore000064400000000000000000000000230072674642500147620ustar 00000000000000Cargo.lock target/ gir-format-check-0.1.3/Cargo.toml0000644000000015610000000000100121600ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] name = "gir-format-check" version = "0.1.3" authors = ["The Gtk-rs Project Developers"] description = "File format checker" homepage = "https://github.com/gtk-rs/gir-format-check" documentation = "https://docs.rs/crate/gir-format-check/" readme = "README.md" keywords = ["gtk-rs", "gir", "check"] license = "MIT" repository = "https://github.com/gtk-rs/gir-format-check" [lib] name = "gir_format_check" gir-format-check-0.1.3/Cargo.toml.orig000064400000000000000000000006360072674642500156730ustar 00000000000000[package] name = "gir-format-check" license = "MIT" homepage = "https://github.com/gtk-rs/gir-format-check" authors = ["The Gtk-rs Project Developers"] keywords = ["gtk-rs", "gir", "check"] readme = "README.md" documentation = "https://docs.rs/crate/gir-format-check/" version = "0.1.3" description = "File format checker" repository = "https://github.com/gtk-rs/gir-format-check" [lib] name = "gir_format_check" gir-format-check-0.1.3/LICENSE000064400000000000000000000020600072674642500140020ustar 00000000000000MIT License Copyright (c) 2018 Guillaume Gomez Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gir-format-check-0.1.3/README.md000064400000000000000000000001110072674642500142470ustar 00000000000000# file-format-check Used to check `Gir.toml` files for `gtk-rs` crates. gir-format-check-0.1.3/src/check_gir.rs000064400000000000000000000127310072674642500160560ustar 00000000000000// Copyright 2013-2018, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use errors::Errors; use utils; use std::cmp::Ordering; use std::path::Path; #[derive(Debug)] struct Elem<'a> { name: &'a str, /// `name` in lowercase. lower: String, pos: usize, associated_comments: Vec, } impl<'a> Elem<'a> { fn new(name: &'a str, pos: usize, associated_comments: &mut Vec) -> Elem<'a> { let ret = Elem { name, lower: name.to_lowercase(), pos, associated_comments: associated_comments.clone(), }; associated_comments.clear(); ret } } impl<'a> Eq for Elem<'a> {} impl<'a> PartialEq for Elem<'a> { fn eq(&self, other: &Elem) -> bool { self.lower == other.lower } } impl<'a> PartialOrd for Elem<'a> { fn partial_cmp(&self, other: &Elem) -> Option { Some(self.cmp(other)) } } impl<'a> Ord for Elem<'a> { fn cmp(&self, other: &Elem) -> Ordering { if self.lower.ends_with('*') { // We always it to be first "because"! Ordering::Less } else { self.lower.cmp(&other.lower) } } } pub fn check_gir_content(content: &str) -> Errors { let lines = content.lines().collect::>(); let mut elems: Vec = Vec::with_capacity(10); let mut objects = Vec::with_capacity(10); let mut in_list = None; let mut in_object = false; let mut errors = 0; let mut messages = Vec::with_capacity(10); let mut associated_comments = Vec::new(); for pos in 0..lines.len() { if lines[pos].ends_with('[') { associated_comments.clear(); in_list = Some(pos); continue; } else if in_list.is_some() && lines[pos].trim() == "]" { if !elems.is_empty() { let mut local_errors = 0; for it in 0..elems.len() - 1 { if elems[it] > elems[it + 1] { messages.push(format!( "ERROR: \"{}\" should be after \"{}\"", elems[it].name, elems[it + 1].name )); local_errors += 1; } } if local_errors > 0 { elems.sort(); messages.push(format!( "\n== Expected output ==\n{}\n{}]", lines[in_list.unwrap()], elems .iter() .map(|l| { if l.associated_comments.is_empty() { format!("{}\n", lines[l.pos]) } else { format!( "{}\n{}\n", l.associated_comments.join("\n"), lines[l.pos] ) } }) .collect::() )); errors += local_errors; } } elems.clear(); in_list = None; } else if in_list.is_some() { let trimmed = lines[pos].trim(); let mut len = trimmed.len(); if trimmed.ends_with("\",") { len -= 2; } else if trimmed.ends_with(',') || trimmed.ends_with('"') { len -= 1; } let start = if trimmed.starts_with('"') { 1 } else { 0 }; let trimmed = &trimmed[start..len]; if trimmed.starts_with('#') { associated_comments.push(lines[pos].to_string()); } else { elems.push(Elem::new(trimmed, pos, &mut associated_comments)); } } else if lines[pos] == "[[object]]" { in_object = true; } else if in_object && lines[pos].starts_with("name = \"") { let trimmed = lines[pos].trim(); let len = trimmed.len() - 1; objects.push(Elem::new( &lines[pos].trim()[8..len], pos, &mut associated_comments, )); } else if lines[pos].trim().is_empty() { in_object = false; } } if !objects.is_empty() { let mut local_errors = 0; for it in 0..objects.len() - 1 { if objects[it] > objects[it + 1] { messages.push(format!( "ERROR: \"{}\" should be after \"{}\"", objects[it].name, objects[it + 1].name )); local_errors += 1; } } if local_errors > 0 { objects.sort(); messages.push(format!( "\n== Expected order ==\n{}", objects .iter() .map(|l| format!("{}\n", l.name)) .collect::() )); errors += local_errors; } } Errors { nb_errors: errors, messages, } } pub fn check_gir_file>(p: P) -> Errors { let content = utils::read_file(p); check_gir_content(&content) } gir-format-check-0.1.3/src/errors.rs000064400000000000000000000010600072674642500154450ustar 00000000000000// Copyright 2013-2018, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::fmt; pub struct Errors { pub messages: Vec, pub nb_errors: usize, } impl Errors { pub fn has_errors(&self) -> bool { self.nb_errors > 0 } } impl fmt::Display for Errors { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.messages.join("\n")) } } gir-format-check-0.1.3/src/lib.rs000064400000000000000000000051410072674642500147030ustar 00000000000000// Copyright 2013-2018, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or mod check_gir; mod errors; mod utils; pub use check_gir::{check_gir_content, check_gir_file}; pub use errors::Errors; #[test] fn simple_check() { let content = r#"something = [ test1, test3, test2, ]"#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 1); } #[test] fn simple_check2() { let content = r#" [[object]] name = "abc" [[object.func]] data = "lol" [[object]] name = "aac" [[object.func]] data = "another" "#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 1); } #[test] fn simple_check3() { let content = r#"something = [ test1, test2, test2 ]"#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 0); } #[test] fn simple_check4() { let content = r#"something = [ "test1", "test3", "test2", ]"#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 1); } #[test] fn check_order_with_comments() { let content = r#"something = [ "test1", #just a comment # on multiple lines "test3", "test2", ]"#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 1); assert_eq!( errors.to_string(), r#"ERROR: "test3" should be after "test2" == Expected output == something = [ "test1", "test2", #just a comment # on multiple lines "test3", ]"# ); } #[test] fn check_order_with_comments2() { let content = r#"something = [ #just a comment # on multiple lines "test3", "test1", "test2", ]"#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 1); assert_eq!( errors.to_string(), r#"ERROR: "test3" should be after "test1" == Expected output == something = [ "test1", "test2", #just a comment # on multiple lines "test3", ]"# ); } #[test] fn check_order_with_comments3() { let content = r#"something = [ #just a comment # on multiple lines "test3", # another comment! "test1", "test2", ]"#; let errors = check_gir_content(content); assert_eq!(errors.nb_errors, 1); assert_eq!( errors.to_string(), r#"ERROR: "test3" should be after "test1" == Expected output == something = [ # another comment! "test1", "test2", #just a comment # on multiple lines "test3", ]"# ); } gir-format-check-0.1.3/src/utils.rs000064400000000000000000000010320072674642500152700ustar 00000000000000// Copyright 2013-2018, The Gtk-rs Project Developers. // See the COPYRIGHT file at the top-level directory of this distribution. // Licensed under the MIT license, see the LICENSE file or use std::fs::File; use std::io::Read; use std::path::Path; pub fn read_file>(p: P) -> String { let mut f = File::open(p).expect("read_file::open failed"); let mut content = String::new(); f.read_to_string(&mut content) .expect("read_file::read_to_end failed"); content }