From 2af99de7e8cf46311764d0472dd559112b472120 Mon Sep 17 00:00:00 2001 From: chrysn Date: Wed, 22 Feb 2023 18:16:32 +0100 Subject: [PATCH] build: Use `syn` to pick out constants --- Cargo.toml | 1 + build.rs | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index df8de3fb..9cca74d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ pin-utils = "0.1" [build-dependencies] shlex = "0.1.1" +syn = { version = "1.0.107", features = [ "parsing" ] } [features] default = [] diff --git a/build.rs b/build.rs index 4d2f3a07..fd09b133 100644 --- a/build.rs +++ b/build.rs @@ -41,12 +41,38 @@ fn main() { let bindgen_output = std::fs::read_to_string(bindgen_output_file) .expect("Failed to read BINDGEN_OUTPUT_FILE"); - // Whether or not the extra space is there depends on whether or not rustfmt is installed. - // FIXME: Find a better way to extract that information - if bindgen_output.contains("pub const CONFIG_AUTO_INIT_ENABLE_DEBUG: u32 = 1;") - || bindgen_output.contains("pub const CONFIG_AUTO_INIT_ENABLE_DEBUG : u32 = 1 ;") - { - println!("cargo:rustc-cfg=marker_config_auto_init_enable_debug"); + const BOOLEAN_FLAGS: &[&str] = &[ + // This decides whether or not some fields are populated ... and unlike with other + // structs, the zeroed default is not a good solution here. (It'd kind of work, but + // it'd produce incorrect debug output). + "CONFIG_AUTO_INIT_ENABLE_DEBUG", + ]; + + let parsed = syn::parse_file(&bindgen_output).expect("Failed to parse bindgen output"); + for item in &parsed.items { + if let syn::Item::Const(const_) = item { + // It's the easiest way to get something we can `contains`... + let ident = const_.ident.to_string(); + if BOOLEAN_FLAGS.contains(&ident.as_str()) { + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Int(litint), + .. + }) = &*const_.expr + { + let value: usize = litint + .base10_parse() + .expect("Identifier is integer literal but not parsable"); + if value != 0 { + println!("cargo:rustc-cfg=marker_{}", ident.to_lowercase()); + } + continue; + } + panic!( + "Found {} but it's not the literal const it was expected to be", + ident + ); + } + } } } else { println!("cargo:warning=Old riot-sys did not provide BINDGEN_OUTPUT_FILE, assuming it's an old RIOT version");