safer_ffi_proc_macros/
_mod.rs

1#![recursion_limit = "256"]
2#![allow(clippy::all)]
3#![cfg_attr(rustfmt, rustfmt::skip)]
4#![allow(nonstandard_style, unused_imports)]
5
6use {
7    ::core::{
8        mem,
9        ops::Not as _,
10        slice,
11    },
12    ::proc_macro::{
13        TokenStream,
14    },
15    ::proc_macro2::{
16        Span,
17        TokenStream as TokenStream2,
18        TokenTree as TT,
19    },
20    ::quote::{
21        format_ident,
22        quote,
23        quote_spanned,
24        ToTokens,
25    },
26    ::syn::{*,
27        parse::{
28            Parse,
29            Parser,
30            ParseStream,
31        },
32        punctuated::Punctuated,
33        spanned::Spanned,
34        Result,
35    },
36    crate::utils::{
37        *,
38    },
39};
40
41#[allow(unused_macros)]
42macro_rules! todo {(
43    $( $fmt:expr $(, $($rest:tt)* )? )?
44) => (
45    ::core::todo! {
46        concat!(file!(), ":", line!(), ":", column!(), " ({})"),
47        ::core::format_args!(
48            concat!($($fmt)?),
49            $($( $($rest)* )?)?
50        ),
51    }
52)}
53
54#[macro_use]
55extern crate macro_rules_attribute;
56
57mod c_str;
58
59#[path = "derives/_mod.rs"]
60mod derives;
61
62#[path = "ffi_export/_mod.rs"]
63mod ffi_export;
64
65#[path = "utils/_mod.rs"]
66mod utils;
67
68#[proc_macro_attribute] pub
69fn cfg_headers (
70    attrs: TokenStream,
71    input: TokenStream,
72) -> TokenStream
73{
74    parse_macro_input!(attrs as parse::Nothing);
75    if cfg!(feature = "headers") {
76        input
77    } else {
78        <_>::default()
79    }
80}
81
82#[proc_macro] pub
83fn c_str (input: TokenStream)
84  -> TokenStream
85{
86    unwrap!(c_str::c_str(input.into()))
87}
88
89#[proc_macro_attribute] pub
90fn ffi_export (attrs: TokenStream, input: TokenStream)
91  -> TokenStream
92{
93    unwrap!(
94        ffi_export::ffi_export(attrs.into(), input.into())
95            .map(utils::mb_file_expanded)
96    )
97}
98
99#[proc_macro_attribute] pub
100fn derive_ReprC (
101    attrs: TokenStream,
102    input: TokenStream,
103) -> TokenStream
104{
105    unwrap!(
106        derives::derive_ReprC(attrs.into(), input.into())
107            .map(utils::mb_file_expanded)
108    )
109}
110
111// #[proc_macro_attribute] pub
112// fn derive_CType (
113//     attrs: TokenStream,
114//     input: TokenStream,
115// ) -> TokenStream
116// {
117//     unwrap!(derives::derive_CType(attrs.into(), input.into()))
118// }
119
120#[proc_macro_attribute] pub
121fn derive_ReprC2 (
122    attrs: TokenStream,
123    input: TokenStream,
124) -> TokenStream
125{
126    unwrap!(
127        derives::repr_c::derive(attrs.into(), input.into())
128            .map(utils::mb_file_expanded)
129    )
130}
131
132#[doc(hidden)] /** Not part of the public API */ #[proc_macro] pub
133fn __respan (
134    input: TokenStream,
135) -> TokenStream
136{
137    let parser = |input: ParseStream<'_>| Result::Ok({
138        let mut contents;
139        ({
140            parenthesized!(contents in input);
141            let tt: ::proc_macro2::TokenTree = contents.parse()?;
142            let _: TokenStream2 = contents.parse()?;
143            tt.span()
144        }, {
145            parenthesized!(contents in input);
146            contents.parse::<TokenStream2>()?
147        })
148    });
149    let (span, tts) = parse_macro_input!(input with parser);
150    respan(span, tts.into()).into()
151}
152
153// where:
154fn respan (
155    span: Span,
156    tts: TokenStream2,
157) -> TokenStream2
158{
159    use ::proc_macro2::{*, TokenStream as TokenStream2};
160    tts.into_iter().map(|mut tt| {
161        if let TokenTree::Group(ref mut g) = tt {
162            let g_span = g.span();
163            *g = Group::new(
164                g.delimiter(),
165                respan(span, g.stream()),
166            );
167            g.set_span(/* span.located_at */ g_span)
168        } else {
169            tt.set_span(
170                span //.located_at(tt.span())
171            );
172        }
173        tt
174    }).collect()
175}