Skip to content

Commit d26fcba

Browse files
committed
correcting
1 parent 36fb52a commit d26fcba

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

bitfields_c2rust/field_type/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ version = "0.5.0"
77
authors = ["Utishnik and C2Rust project"]
88
edition = "2024"
99

10+
[features]
11+
default = ["std"] #default std
12+
std = []
13+
no_std = []
14+
1015
[lib]
1116
name = "bitfield_c2rust_api_field_type"
1217
path = "lib.rs"

bitfields_c2rust/field_type/lib.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#![cfg_attr(feature = "no_std", no_std)]
2+
3+
pub trait FieldType: Sized {
4+
const IS_SIGNED: bool;
5+
6+
#[cfg(not(feature = "no_std"))]
7+
const TOTAL_BIT_SIZE: usize = ::std::mem::size_of::<Self>() * 8;
8+
#[cfg(feature = "no_std")]
9+
const TOTAL_BIT_SIZE: usize = ::core::mem::size_of::<Self>() * 8;
10+
11+
fn get_bit(&self, bit: usize) -> bool;
12+
13+
fn set_field(&self, field: &mut [u8], bit_range: (usize, usize)) {
14+
fn zero_bit(byte: &mut u8, n_bit: u64) {
15+
let bit: i32 = 1 << n_bit;
16+
17+
*byte &= !bit as u8;
18+
}
19+
20+
fn one_bit(byte: &mut u8, n_bit: u64) {
21+
let bit: i32 = 1 << n_bit;
22+
23+
*byte |= bit as u8;
24+
}
25+
26+
let (lhs_bit, rhs_bit) = bit_range;
27+
28+
for (i, bit_index) in (lhs_bit..=rhs_bit).enumerate() {
29+
let byte_index: usize = bit_index / 8;
30+
let byte: &mut u8 = &mut field[byte_index];
31+
32+
if self.get_bit(i) {
33+
one_bit(byte, (bit_index % 8) as u64);
34+
} else {
35+
zero_bit(byte, (bit_index % 8) as u64);
36+
}
37+
}
38+
}
39+
40+
fn get_field(field: &[u8], bit_range: (usize, usize)) -> Self;
41+
}
42+
43+
macro_rules! impl_int {
44+
($($typ: ident),+) => {
45+
$(
46+
impl FieldType for $typ {
47+
const IS_SIGNED: bool = $typ::MIN != 0;
48+
49+
fn get_bit(&self, bit: usize) -> bool {
50+
((*self >> bit) & 1) == 1
51+
}
52+
53+
fn get_field(field: &[u8], bit_range: (usize, usize)) -> Self {
54+
let (lhs_bit, rhs_bit) = bit_range;
55+
let mut val = 0;
56+
57+
for (i, bit_index) in (lhs_bit..=rhs_bit).enumerate() {
58+
let byte_index = bit_index / 8;
59+
let byte = field[byte_index];
60+
let bit = 1 << (bit_index % 8);
61+
let read_bit = byte & bit;
62+
63+
if read_bit != 0 {
64+
let write_bit = 1 << i;
65+
66+
val |= write_bit;
67+
}
68+
}
69+
70+
// If the int type is signed, sign extend unconditionally
71+
if Self::IS_SIGNED {
72+
let bit_width = rhs_bit - lhs_bit + 1;
73+
let unused_bits = Self::TOTAL_BIT_SIZE - bit_width;
74+
75+
val <<= unused_bits;
76+
val >>= unused_bits;
77+
}
78+
79+
val
80+
}
81+
}
82+
)+
83+
};
84+
}
85+
86+
impl_int! {u8, u16, u32, u64, u128, i8, i16, i32, i64, i128}
87+
88+
impl FieldType for bool {
89+
const IS_SIGNED: bool = false;
90+
91+
fn get_bit(&self, _bit: usize) -> bool {
92+
*self
93+
}
94+
95+
fn get_field(field: &[u8], bit_range: (usize, usize)) -> Self {
96+
let (lhs_bit, rhs_bit) = bit_range;
97+
let mut val: bool = false;
98+
99+
for bit_index in lhs_bit..=rhs_bit {
100+
let byte_index: usize = bit_index / 8;
101+
let byte: u8 = field[byte_index];
102+
let bit: u8 = 1 << (bit_index % 8);
103+
let read_bit: u8 = byte & bit;
104+
105+
if read_bit != 0 {
106+
val = true;
107+
}
108+
}
109+
110+
val
111+
}
112+
}

bitfields_c2rust/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ fn bitfield_struct_impl(struct_item: ItemStruct) -> Result<TokenStream, Error> {
185185
let bitfields: Result<Vec<BFFieldAttr>, Error> =
186186
fields.iter().flat_map(filter_and_parse_fields).collect();
187187
let bitfields: Vec<BFFieldAttr> = bitfields?;
188-
let field_types: Vec<_ > = bitfields.iter().map(parse_bitfield_ty_path).collect();
188+
let field_types: Vec<_> = bitfields.iter().map(parse_bitfield_ty_path).collect();
189189
let field_types_return: &Vec<Path> = &field_types;
190190
let field_types_typedef: &Vec<Path> = &field_types;
191191
let field_types_setter_arg: &Vec<Path> = &field_types;

0 commit comments

Comments
 (0)