|
| 1 | +//! Procedural macros for gdbstub regression testing. |
| 2 | +
|
| 3 | +use proc_macro::TokenStream; |
| 4 | +use quote::quote; |
| 5 | +use syn::{parse_macro_input, ItemFn}; |
| 6 | + |
| 7 | +/// Attribute macro to wrap a test function with gdbstub regression testing boilerplate. |
| 8 | +#[proc_macro_attribute] |
| 9 | +pub fn gdbstub_test(args: TokenStream, input: TokenStream) -> TokenStream { |
| 10 | + let args_str = args.to_string().replace(" ", ""); |
| 11 | + let mut parts = args_str.split(','); |
| 12 | + let target = parts.next().unwrap().to_string(); |
| 13 | + let is_extended = parts.next() == Some("extended"); |
| 14 | + |
| 15 | + let input = parse_macro_input!(input as ItemFn); |
| 16 | + |
| 17 | + let name = &input.sig.ident; |
| 18 | + let body = &input.block; |
| 19 | + let attrs = &input.attrs; |
| 20 | + let vis = &input.vis; |
| 21 | + |
| 22 | + let result = quote! { |
| 23 | + #[test] |
| 24 | + #(#attrs)* |
| 25 | + #vis fn #name() -> anyhow::Result<()> { |
| 26 | + use anyhow::Context; |
| 27 | + let target = #target; |
| 28 | + let test_elf = gdbstub_test::find_test_elf(target); |
| 29 | + if !test_elf.exists() { |
| 30 | + anyhow::bail!("Test ELF not found at {:?}. Did you build the examples?", test_elf); |
| 31 | + } |
| 32 | + |
| 33 | + let emu = gdbstub_test::EmulatorProcess::spawn(target).context("failed to spawn emulator")?; |
| 34 | + let mut gdb = gdbstub_test::GdbMiClient::spawn(None, test_elf.to_str().unwrap()).context("failed to spawn gdb")?; |
| 35 | + |
| 36 | + if #is_extended { |
| 37 | + gdb.connect_extended_uds(emu.uds_path().to_str().unwrap()).context("failed to connect gdb to emulator in extended mode")?; |
| 38 | + } else { |
| 39 | + gdb.connect_uds(emu.uds_path().to_str().unwrap()).context("failed to connect gdb to emulator")?; |
| 40 | + } |
| 41 | + |
| 42 | + let mut func = |mut gdb: gdbstub_test::GdbMiClient| -> anyhow::Result<()> { |
| 43 | + #body |
| 44 | + }; |
| 45 | + |
| 46 | + func(gdb) |
| 47 | + } |
| 48 | + }; |
| 49 | + |
| 50 | + result.into() |
| 51 | +} |
0 commit comments