Skip to content

Commit

Permalink
validate macro input
Browse files Browse the repository at this point in the history
  • Loading branch information
pickx committed Jul 17, 2023
1 parent d1dfdc3 commit 4e5c550
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 41 deletions.
15 changes: 2 additions & 13 deletions bilge-impl/src/bitsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ struct ItemIr {
expanded: TokenStream,
}

pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
let (item, declared_bitsize) = parse(item, args);
pub(super) fn bitsize(args: TokenStream, item: Item) -> TokenStream {
let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args);
let attrs = SplitAttributes::from_item(&item);
let ir = match item {
Item::Struct(mut item) => {
Expand All @@ -33,17 +33,6 @@ pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
generate_common(ir, attrs, declared_bitsize)
}

fn parse(item: TokenStream, args: TokenStream) -> (Item, BitSize) {
let item = syn::parse2(item).unwrap_or_else(unreachable);

if args.is_empty() {
abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`")
}

let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args);
(item, declared_bitsize)
}

fn check_type_is_supported(ty: &Type) {
use Type::*;
match ty {
Expand Down
7 changes: 1 addition & 6 deletions bilge-impl/src/fmt_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{Data, DeriveInput, Fields, Variant, punctuated::Iter};

pub(crate) fn binary(item: TokenStream) -> TokenStream {
let derive_input = parse(item);
pub(crate) fn binary(derive_input: DeriveInput) -> TokenStream {
let (derive_data, arb_int, name, bitsize, ..) = analyze(&derive_input);

match derive_data {
Expand Down Expand Up @@ -86,10 +85,6 @@ fn generate_to_int_match_arms(variants: Iter<Variant>, enum_name: &Ident, bitsiz
.collect()
}

fn parse(item: TokenStream) -> DeriveInput {
shared::parse_derive(item)
}

fn analyze(derive_input: &DeriveInput) -> (&Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
shared::analyze_derive(derive_input, false)
}
7 changes: 1 addition & 6 deletions bilge-impl/src/from_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use quote::quote;
use syn::{Type, Fields, DeriveInput, Data, punctuated::Iter, Variant};
use crate::shared::{fallback::Fallback, self, BitSize, unreachable, discriminant_assigner::DiscriminantAssigner, enum_fills_bitsize};

pub(super) fn from_bits(item: TokenStream) -> TokenStream {
let derive_input = parse(item);
pub(super) fn from_bits(derive_input: DeriveInput) -> TokenStream {
let (derive_data, arb_int, name, internal_bitsize, fallback) = analyze(&derive_input);
let expanded = match &derive_data {
Data::Struct(struct_data) => {
Expand All @@ -22,10 +21,6 @@ pub(super) fn from_bits(item: TokenStream) -> TokenStream {
generate_common(expanded)
}

fn parse(item: TokenStream) -> DeriveInput {
shared::parse_derive(item)
}

fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
shared::analyze_derive(derive_input, false)
}
Expand Down
33 changes: 23 additions & 10 deletions bilge-impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;
use syn::parse_macro_input;

mod bitsize;
mod bitsize_internal;
Expand All @@ -19,15 +20,19 @@ mod shared;
#[proc_macro_error]
#[proc_macro_attribute]
pub fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
bitsize::bitsize(args.into(), item.into()).into()
let item = parse_macro_input!(item);

bitsize::bitsize(args.into(), item).into()
}

/// This is internally used, not to be used by anything besides `bitsize`.
/// No guarantees are given.
#[proc_macro_error]
#[proc_macro_attribute]
pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream {
bitsize_internal::bitsize_internal(args.into(), item.into()).into()
let item = parse_macro_input!(item);

bitsize_internal::bitsize_internal(args.into(), item).into()
}

/// Generate an `impl TryFrom<uN>` for unfilled bitfields.
Expand All @@ -36,8 +41,10 @@ pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream {
/// a struct don't fill their given `bitsize`.
#[proc_macro_error]
#[proc_macro_derive(TryFromBits, attributes(bitsize_internal, fallback))]
pub fn derive_try_from_bits(item: TokenStream) -> TokenStream {
try_from_bits::try_from_bits(item.into()).into()
pub fn derive_try_from_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

try_from_bits::try_from_bits(derive_input).into()
}

/// Generate an `impl From<uN>` for filled bitfields.
Expand All @@ -47,22 +54,28 @@ pub fn derive_try_from_bits(item: TokenStream) -> TokenStream {
/// using enums.
#[proc_macro_error]
#[proc_macro_derive(FromBits, attributes(bitsize_internal, fallback))]
pub fn derive_from_bits(item: TokenStream) -> TokenStream {
from_bits::from_bits(item.into()).into()
pub fn derive_from_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

from_bits::from_bits(derive_input).into()
}

/// Generate an `impl Debug` for bitfield structs.
///
/// Please use normal #[derive(Debug)] for enums.
#[proc_macro_error]
#[proc_macro_derive(DebugBits, attributes(bitsize_internal))]
pub fn debug_bits(item: TokenStream) -> TokenStream {
debug_bits::debug_bits(item.into()).into()
pub fn debug_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

debug_bits::debug_bits(derive_input).into()
}

/// Generate an `impl core::fmt::Binary` for bitfields.
#[proc_macro_error]
#[proc_macro_derive(BinaryBits)]
pub fn derive_binary_bits(item: TokenStream) -> TokenStream {
fmt_bits::binary(item.into()).into()
pub fn derive_binary_bits(derive_input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(derive_input);

fmt_bits::binary(derive_input).into()
}
4 changes: 4 additions & 0 deletions bilge-impl/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ pub(crate) fn analyze_derive(derive_input: &DeriveInput, try_from: bool) -> (&sy

// If we want to support bitsize(u4) besides bitsize(4), do that here.
pub fn bitsize_and_arbitrary_int_from(bitsize_arg: TokenStream) -> (BitSize, TokenStream) {
if bitsize_arg.is_empty() {
abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`")
}

let bitsize: LitInt = syn::parse2(bitsize_arg.clone()).unwrap_or_else(|_|
abort!(bitsize_arg, "attribute value is not a number"; help = "you need to define the size like this: `#[bitsize(32)]`")
);
Expand Down
7 changes: 1 addition & 6 deletions bilge-impl/src/try_from_bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use syn::{DeriveInput, Data, punctuated::Iter, Variant, Type, Fields};
use crate::shared::{last_ident_of_path, bitsize_from_type_ident};
use crate::shared::{fallback::Fallback, self, BitSize, unreachable, enum_fills_bitsize, discriminant_assigner::DiscriminantAssigner};

pub(super) fn try_from_bits(item: TokenStream) -> TokenStream {
let derive_input = parse(item);
pub(super) fn try_from_bits(derive_input: DeriveInput) -> TokenStream {
let (derive_data, arb_int, name, internal_bitsize, ..) = analyze(&derive_input);
match derive_data {
Data::Struct(ref data) => {
Expand All @@ -21,10 +20,6 @@ pub(super) fn try_from_bits(item: TokenStream) -> TokenStream {
}
}

fn parse(item: TokenStream) -> DeriveInput {
shared::parse_derive(item)
}

fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
shared::analyze_derive(derive_input, true)
}
Expand Down

0 comments on commit 4e5c550

Please sign in to comment.