Skip to content

Commit d7adfc4

Browse files
committed
transpile: Factor out function for getting bytes of a literal
1 parent cf1c95a commit d7adfc4

File tree

3 files changed

+46
-41
lines changed

3 files changed

+46
-41
lines changed

c2rust-transpile/src/translator/literals.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -151,31 +151,42 @@ impl<'c> Translation<'c> {
151151
Ok(WithStmts::new_val(val))
152152
}
153153

154-
CLiteral::String(ref val, width) => {
155-
let mut val = val.to_owned();
156-
let num_elems = match self.ast_context.resolve_type(ty.ctype).kind {
157-
CTypeKind::ConstantArray(_elem_ty, num_elems) => num_elems,
158-
ref kind => {
159-
panic!("String literal with unknown size: {val:?}, kind = {kind:?}")
160-
}
161-
};
162-
163-
// Match the literal size to the expected size padding with zeros as needed
164-
let size = num_elems * (width as usize);
165-
val.resize(size, 0);
154+
CLiteral::String(ref bytes, element_size) => {
155+
let bytes_padded = self.string_literal_bytes(ty.ctype, bytes, element_size);
166156

167157
// std::mem::transmute::<[u8; size], ctype>(*b"xxxx")
168-
let u8_ty = mk().path_ty(vec!["u8"]);
169-
let width_lit = mk().lit_expr(mk().int_unsuffixed_lit(val.len() as u128));
170-
Ok(WithStmts::new_unsafe_val(transmute_expr(
171-
mk().array_ty(u8_ty, width_lit),
158+
let array_ty = mk().array_ty(
159+
mk().ident_ty("u8"),
160+
mk().lit_expr(bytes_padded.len() as u128),
161+
);
162+
let val = transmute_expr(
163+
array_ty,
172164
self.convert_type(ty.ctype)?,
173-
mk().unary_expr(UnOp::Deref(Default::default()), mk().lit_expr(val)),
174-
)))
165+
mk().unary_expr(UnOp::Deref(Default::default()), mk().lit_expr(bytes_padded)),
166+
);
167+
Ok(WithStmts::new_unsafe_val(val))
175168
}
176169
}
177170
}
178171

172+
/// Returns the bytes of a string literal, including any additional zero bytes to pad the
173+
/// literal to the expected size.
174+
pub fn string_literal_bytes(&self, ctype: CTypeId, bytes: &[u8], element_size: u8) -> Vec<u8> {
175+
let num_elems = match self.ast_context.resolve_type(ctype).kind {
176+
CTypeKind::ConstantArray(_, num_elems) => num_elems,
177+
ref kind => {
178+
panic!("String literal with unknown size: {bytes:?}, kind = {kind:?}")
179+
}
180+
};
181+
182+
let size = num_elems * (element_size as usize);
183+
let mut bytes_padded = Vec::with_capacity(size);
184+
bytes_padded.extend(bytes);
185+
bytes_padded.resize(size, 0);
186+
187+
bytes_padded
188+
}
189+
179190
/// Convert an initialization list into an expression. These initialization lists can be
180191
/// used as array literals, struct literals, and union literals in code.
181192
pub fn convert_init_list(

c2rust-transpile/src/translator/mod.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4729,16 +4729,20 @@ impl<'c> Translation<'c> {
47294729
})
47304730
.unwrap_or(false);
47314731
match expr_kind {
4732-
Some(&CExprKind::Literal(_, CLiteral::String(ref bytes, 1)))
4733-
if is_const && !translate_as_macro =>
4734-
{
4732+
Some(&CExprKind::Literal(
4733+
literal_cqual_type,
4734+
CLiteral::String(ref bytes, element_size @ 1),
4735+
)) if is_const && !translate_as_macro => {
47354736
let target_ty = self.convert_type(target_cty.ctype)?;
47364737

4737-
let mut bytes = bytes.to_owned();
4738-
bytes.push(0);
4739-
let byte_literal = mk().lit_expr(bytes);
4740-
let val =
4741-
mk().cast_expr(byte_literal, mk().ptr_ty(mk().path_ty(vec!["u8"])));
4738+
let bytes_padded = self.string_literal_bytes(
4739+
literal_cqual_type.ctype,
4740+
bytes,
4741+
element_size,
4742+
);
4743+
let element_ty = mk().ident_ty("u8");
4744+
let bytes_literal = mk().lit_expr(bytes_padded);
4745+
let val = mk().cast_expr(bytes_literal, mk().ptr_ty(element_ty));
47424746
let val = mk().cast_expr(val, target_ty);
47434747
Ok(WithStmts::new_val(val))
47444748
}

c2rust-transpile/src/translator/operators.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -968,21 +968,11 @@ impl<'c> Translation<'c> {
968968
false,
969969
) = (expr_kind, translate_as_macro)
970970
{
971-
let num_elems =
972-
match self.ast_context.resolve_type(literal_cqual_type.ctype).kind {
973-
CTypeKind::ConstantArray(_, num_elems) => num_elems,
974-
ref kind => {
975-
panic!(
976-
"String literal with unknown size: {bytes:?}, kind = {kind:?}"
977-
)
978-
}
979-
};
980-
981-
// Match the literal size to the expected size padding with zeros as needed
982-
let size = num_elems * (element_size as usize);
983-
let mut bytes_padded = Vec::with_capacity(size);
984-
bytes_padded.extend(bytes);
985-
bytes_padded.resize(size, 0);
971+
let bytes_padded = self.string_literal_bytes(
972+
literal_cqual_type.ctype,
973+
bytes,
974+
element_size,
975+
);
986976

987977
let array_ty = mk().array_ty(
988978
mk().ident_ty("u8"),

0 commit comments

Comments
 (0)