Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48639e1c authored by Martin Geisler's avatar Martin Geisler Committed by Gerrit Code Review
Browse files

Merge changes I756a70ad,I52bc81b7,I8784b439

* changes:
  pdl: Add u64 or usize suffix to mask_bit output
  pdl: Derive Clone + PartialEq + Eq for data structs
  pdl: Fix parsing of reserved fields
parents 15c02e84 e7849d25
Loading
Loading
Loading
Loading
+24 −12
Original line number Diff line number Diff line
@@ -38,10 +38,22 @@ macro_rules! quote_block {
}

/// Generate a bit-mask which masks out `n` least significant bits.
pub fn mask_bits(n: usize) -> syn::LitInt {
    // The literal needs a suffix if it's larger than an i32.
    let suffix = if n > 31 { "u64" } else { "" };
    syn::parse_str::<syn::LitInt>(&format!("{:#x}{suffix}", (1u64 << n) - 1)).unwrap()
///
/// Literal integers in Rust default to the `i32` type. For this
/// reason, if `n` is larger than 31, a suffix is added to the
/// `LitInt` returned. This should either be `u64` or `usize`
/// depending on where the result is used.
pub fn mask_bits(n: usize, suffix: &str) -> syn::LitInt {
    let suffix = if n > 31 { format!("_{suffix}") } else { String::new() };
    // Format the hex digits as 0x1111_2222_3333_usize.
    let hex_digits = format!("{:x}", (1u64 << n) - 1)
        .as_bytes()
        .rchunks(4)
        .rev()
        .map(|chunk| std::str::from_utf8(chunk).unwrap())
        .collect::<Vec<&str>>()
        .join("_");
    syn::parse_str::<syn::LitInt>(&format!("0x{hex_digits}{suffix}")).unwrap()
}

fn generate_packet_size_getter(
@@ -219,7 +231,7 @@ fn generate_data_struct(
    let child_field = has_children_or_payload.then(|| quote!(child));

    let data_struct_decl = quote! {
        #[derive(Debug)]
        #[derive(Debug, Clone, PartialEq, Eq)]
        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
        pub struct #id_data {
            #field_declarations
@@ -435,7 +447,7 @@ fn generate_packet_decl(
    });
    let child_declaration = has_children_or_payload.then(|| {
        quote! {
            #[derive(Debug)]
            #[derive(Debug, Clone, PartialEq, Eq)]
            #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
            pub enum #id_data_child {
                #(#child(Arc<#child_data>),)*
@@ -453,7 +465,7 @@ fn generate_packet_decl(
                }
            }

            #[derive(Debug)]
            #[derive(Debug, Clone, PartialEq, Eq)]
            #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
            pub enum #id_child {
                #(#child(#child),)*
@@ -496,7 +508,7 @@ fn generate_packet_decl(

        #data_struct_decl

        #[derive(Debug, Clone)]
        #[derive(Debug, Clone, PartialEq, Eq)]
        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
        pub struct #id_packet {
            #(
@@ -919,12 +931,12 @@ mod tests {
        packet_decl_array_unknown_element_width_dynamic_size,
        "
          struct Foo {
            _count_(a): 8,
            _count_(a): 40,
            a: 16[],
          }

          packet Bar {
            _size_(x): 8,
            _size_(x): 40,
            x: Foo[],
          }
        "
@@ -934,12 +946,12 @@ mod tests {
        packet_decl_array_unknown_element_width_dynamic_count,
        "
          struct Foo {
            _count_(a): 8,
            _count_(a): 40,
            a: 16[],
          }

          packet Bar {
            _count_(x): 8,
            _count_(x): 40,
            x: Foo[],
          }
        "
+13 −3
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ impl<'a> FieldParser<'a> {
            if !single_value && width < value_type.width {
                // Mask value if we grabbed more than `width` and if
                // `as #value_type` doesn't already do the masking.
                let mask = mask_bits(width);
                let mask = mask_bits(width, "u64");
                v = quote! { (#v & #mask) };
            }

@@ -165,9 +165,19 @@ impl<'a> FieldParser<'a> {
                    }
                }
                ast::FieldDesc::Reserved { .. } => {
                    // Nothing to do here.
                    if single_value {
                        let span = self.span;
                        let size = proc_macro2::Literal::usize_unsuffixed(size);
                        quote! {
                            #span.get_mut().advance(#size);
                        }
                    } else {
                        //  Otherwise we don't need anything: we will
                        //  have advanced past the reserved field when
                        //  reading the chunk above.
                        quote! {}
                    }
                }
                ast::FieldDesc::Size { field_id, .. } => {
                    let id = size_field_ident(field_id);
                    quote! {
+3 −3
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ impl<'a> FieldSerializer<'a> {
                let field_type = types::Integer::new(*width);
                if field_type.width > *width {
                    let packet_name = &self.packet_name;
                    let max_value = mask_bits(*width);
                    let max_value = mask_bits(*width, "u64");
                    self.code.push(quote! {
                        if self.#field_name > #max_value {
                            panic!(
@@ -105,7 +105,7 @@ impl<'a> FieldSerializer<'a> {
            }
            ast::FieldDesc::Size { field_id, width, .. } => {
                let packet_name = &self.packet_name;
                let max_value = mask_bits(*width);
                let max_value = mask_bits(*width, "usize");

                let decl = self.scope.typedef.get(self.packet_name).unwrap();
                let scope = self.scope.scopes.get(decl).unwrap();
@@ -165,7 +165,7 @@ impl<'a> FieldSerializer<'a> {
                let field_type = types::Integer::new(*width);
                if field_type.width > *width {
                    let packet_name = &self.packet_name;
                    let max_value = mask_bits(*width);
                    let max_value = mask_bits(*width, "usize");
                    self.code.push(quote! {
                        if self.#field_name.len() > #max_value {
                            panic!(
+2 −2
Original line number Diff line number Diff line
@@ -82,12 +82,12 @@ impl<'de> serde::Deserialize<'de> for Foo {
    }
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BarData {
    x: [Foo; 5],
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Bar {
    #[cfg_attr(feature = "serde", serde(flatten))]
+2 −2
Original line number Diff line number Diff line
@@ -82,12 +82,12 @@ impl<'de> serde::Deserialize<'de> for Foo {
    }
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BarData {
    x: [Foo; 5],
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Bar {
    #[cfg_attr(feature = "serde", serde(flatten))]
Loading