Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,11 @@ bool Converter::GetFmtArg(clang::Expr *arg, std::string &fmt,
std::string &fmt_args, const char *&fmt_trait,
std::string &fmt_width) {
std::string arg_str = Mapper::ToString(arg);
if (clang::isa<clang::StringLiteral>(arg->IgnoreImplicit())) {
if (auto *str_lit =
clang::dyn_cast<clang::StringLiteral>(arg->IgnoreImplicit())) {
if (!IsAsciiStringLiteral(str_lit)) {
return false;
}
auto str = GetEscapedStringLiteral(arg);
std::string_view trim(str);
// Delete " from string
Expand Down Expand Up @@ -1299,6 +1303,8 @@ bool Converter::GetRawArg(clang::Expr *arg, std::string &raw_args) {
raw_args += "(&(" + str + ")[..(" + str + ").len() - 1]";
} else if (Mapper::ToString(arg).contains("std::endl")) {
raw_args += "(&[b'\\n']";
} else if (clang::isa<clang::StringLiteral>(arg->IgnoreImplicit())) {
raw_args += "(b" + GetEscapedStringLiteral(arg);
} else {
return false;
}
Expand Down Expand Up @@ -1700,8 +1706,9 @@ bool Converter::VisitFloatingLiteral(clang::FloatingLiteral *expr) {
}

bool Converter::VisitCharacterLiteral(clang::CharacterLiteral *expr) {
auto uc = static_cast<unsigned char>(expr->getValue());
std::string ch = GetEscapedCharLiteral(expr->getValue());
ch = "'" + std::move(ch) + "'";
ch = (uc > 0x7F ? "b'" : "'") + std::move(ch) + '\'';
{
PushParen paren(*this);
StrCat(ch, keyword::kAs, ToStringBase(expr->getType()));
Expand All @@ -1728,7 +1735,7 @@ std::string Converter::GetEscapedCharLiteral(char character) const {
return "\\0";
}
auto uc = static_cast<unsigned char>(character);
if (uc < 0x20 || uc == 0x7F) {
if (uc < 0x20 || uc >= 0x7F) {
return std::format("\\x{:02x}", uc);
}
return std::string(1, character);
Expand Down
9 changes: 9 additions & 0 deletions cpp2rust/converter/converter_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,15 @@ bool IsCallToOstream(clang::CallExpr *expr) {
return false;
}

bool IsAsciiStringLiteral(const clang::StringLiteral *str) {
for (unsigned char c : str->getString()) {
if (c > 0x7F) {
return false;
}
}
return true;
}

std::vector<clang::CXXConstructorDecl *>
GetTemplateInstantiatedCtors(clang::CXXRecordDecl *decl) {
std::vector<clang::CXXConstructorDecl *> out;
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/converter_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ bool IsUniquePtr(clang::QualType type);

bool IsCallToOstream(clang::CallExpr *expr);

bool IsAsciiStringLiteral(const clang::StringLiteral *str);

std::vector<clang::CXXConstructorDecl *>
GetTemplateInstantiatedCtors(clang::CXXRecordDecl *decl);

Expand Down
2 changes: 1 addition & 1 deletion cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) {
GetEscapedStringLiteral(expr, pad)));
return false;
}
StrCat(GetEscapedStringLiteral(expr));
StrCat(std::format("b{}", GetEscapedStringLiteral(expr, 0)));
return false;
}

Expand Down
9 changes: 5 additions & 4 deletions libcc2rs/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,9 +940,10 @@ impl fmt::Display for Ptr<u8> {
}
}

type StringLiteralMap = HashMap<&'static [u8], Rc<RefCell<Vec<u8>>>>;

thread_local! {
static STRING_LITERALS: RefCell<HashMap<&'static str, Rc<RefCell<Vec<u8>>>>> =
RefCell::new(HashMap::new());
static STRING_LITERALS: RefCell<StringLiteralMap> = RefCell::new(HashMap::new());
}

impl Ptr<u8> {
Expand Down Expand Up @@ -1020,12 +1021,12 @@ impl Ptr<u8> {
}

#[inline]
pub fn from_string_literal(s: &'static str) -> Self {
pub fn from_string_literal(s: &'static [u8]) -> Self {
STRING_LITERALS.with(|literals| {
let mut literals = literals.borrow_mut();
let weak = Rc::downgrade(literals.entry(s).or_insert_with(|| {
Rc::new(RefCell::new({
let mut v = s.as_bytes().to_vec();
let mut v = s.to_vec();
v.push(0);
v
}))
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/bool_condition_logical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn main_0() -> i32 {
if ((*n.borrow()) != 0) || (((*bits.borrow()) & 256_i64) != 0) {
assert!(true);
}
let cp: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal("hi")));
let cp: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal(b"hi")));
let cnp: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::<u8>::null()));
if ((*x.borrow()) > (*y.borrow())) && (!(*cp.borrow()).is_null()) {
assert!(true);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/bool_condition_logical_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ fn main_0() -> i32 {
{
assert!((1 != 0));
}
let cp: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal("hi")));
let cp: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal(b"hi")));
let cnp: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::<u8>::null()));
if (((((((*x.borrow()) > (*y.borrow())) as i32) != 0) && (!(*cp.borrow()).is_null())) as i32)
!= 0)
Expand Down
16 changes: 10 additions & 6 deletions tests/unit/out/refcount/char_printing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main_0() -> i32 {
let vec_: Value<Vec<u8>> = Rc::new(RefCell::new(vec![195_u8, 167_u8]));
let i: Value<i32> = Rc::new(RefCell::new(27));
let str: Value<Vec<u8>> = Rc::new(RefCell::new(
Ptr::from_string_literal("rdas.")
Ptr::from_string_literal(b"rdas.")
.to_c_string_iterator()
.chain(std::iter::once(0))
.collect::<Vec<u8>>(),
Expand All @@ -29,12 +29,16 @@ fn main_0() -> i32 {
]
.concat()),
);
write!(
libcc2rs::cout(),
"0x{:x} açordas?\nSim, 0x{:x}.\n",
27,
(*i.borrow()),
write!(libcc2rs::cout(), "0x{:x}", 27,);
libcc2rs::cout().write_all(
&([
(b" a\xc3\xa7ordas?" as &[u8]),
(&[('\n' as u8)] as &[u8]),
(b"Sim, 0x" as &[u8]),
]
.concat()),
);
write!(libcc2rs::cout(), "{:x}.\n", (*i.borrow()),);
write!(libcc2rs::cout(), "Hello, World!\n",);
libcc2rs::cout().write_all(
&([
Expand Down
16 changes: 10 additions & 6 deletions tests/unit/out/refcount/char_printing_cerr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main_0() -> i32 {
let vec_: Value<Vec<u8>> = Rc::new(RefCell::new(vec![195_u8, 167_u8]));
let i: Value<i32> = Rc::new(RefCell::new(27));
let str: Value<Vec<u8>> = Rc::new(RefCell::new(
Ptr::from_string_literal("rdas.")
Ptr::from_string_literal(b"rdas.")
.to_c_string_iterator()
.chain(std::iter::once(0))
.collect::<Vec<u8>>(),
Expand All @@ -29,12 +29,16 @@ fn main_0() -> i32 {
]
.concat()),
);
write!(
libcc2rs::cerr(),
"0x{:x} açordas?\nSim, 0x{:x}.\n",
27,
(*i.borrow()),
write!(libcc2rs::cerr(), "0x{:x}", 27,);
libcc2rs::cerr().write_all(
&([
(b" a\xc3\xa7ordas?" as &[u8]),
(&[('\n' as u8)] as &[u8]),
(b"Sim, 0x" as &[u8]),
]
.concat()),
);
write!(libcc2rs::cerr(), "{:x}.\n", (*i.borrow()),);
write!(libcc2rs::cerr(), "Hello, World!\n",);
libcc2rs::cerr().write_all(
&([
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/out/refcount/default_in_statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ thread_local!(
);
thread_local!(
pub static static_foo_3: Value<Foo> = Rc::new(RefCell::new(Foo {
s1: Rc::new(RefCell::new(Ptr::from_string_literal("hello"))),
s1: Rc::new(RefCell::new(Ptr::from_string_literal(b"hello"))),
s2: Rc::new(RefCell::new(Ptr::<u8>::null())),
fn1: Rc::new(RefCell::new(FnPtr::null())),
fn2: Rc::new(RefCell::new(FnPtr::null())),
Expand All @@ -121,14 +121,14 @@ thread_local!(
thread_local!(
pub static static_foo_array_4: Value<Box<[Foo]>> = Rc::new(RefCell::new(Box::new([
Foo {
s1: Rc::new(RefCell::new(Ptr::from_string_literal("first"))),
s1: Rc::new(RefCell::new(Ptr::from_string_literal(b"first"))),
s2: Rc::new(RefCell::new(Ptr::<u8>::null())),
fn1: Rc::new(RefCell::new(FnPtr::null())),
fn2: Rc::new(RefCell::new(FnPtr::null())),
n: Rc::new(RefCell::new(1)),
},
Foo {
s1: Rc::new(RefCell::new(Ptr::from_string_literal("second"))),
s1: Rc::new(RefCell::new(Ptr::from_string_literal(b"second"))),
s2: Rc::new(RefCell::new(Ptr::<u8>::null())),
fn1: Rc::new(RefCell::new(FnPtr::null())),
fn2: Rc::new(RefCell::new(FnPtr::null())),
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/out/refcount/enum_int_interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,17 @@ thread_local!(
thread_local!(
pub static entries_3: Value<Box<[Entry]>> = Rc::new(RefCell::new(Box::new([
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("first"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"first"))),
color: Rc::new(RefCell::new(Color::RED)),
opt: Rc::new(RefCell::new(Option::OPT_NONE)),
},
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("second"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"second"))),
color: Rc::new(RefCell::new(Color::GREEN)),
opt: Rc::new(RefCell::new(Option::OPT_A)),
},
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("third"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"third"))),
color: Rc::new(RefCell::new(Color::BLUE)),
opt: Rc::new(RefCell::new(Option::OPT_C)),
},
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/out/refcount/enum_int_interop_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,17 @@ thread_local!(
thread_local!(
pub static entries_3: Value<Box<[Entry]>> = Rc::new(RefCell::new(Box::new([
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("first"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"first"))),
color: Rc::new(RefCell::new(Color::RED)),
opt: Rc::new(RefCell::new(Option::OPT_NONE)),
},
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("second"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"second"))),
color: Rc::new(RefCell::new(Color::GREEN)),
opt: Rc::new(RefCell::new(Option::OPT_A)),
},
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("third"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"third"))),
color: Rc::new(RefCell::new(Color::BLUE)),
opt: Rc::new(RefCell::new(Option::OPT_C)),
},
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/expr_as_bool_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn main_0() -> i32 {
assert!(((((*eq.borrow()) == 1) as i32) != 0));
assert!(((((*lt.borrow()) == 0) as i32) != 0));
assert!(((((*neq.borrow()) == 0) as i32) != 0));
let p1: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal("hi")));
let p1: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal(b"hi")));
let p2: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::<u8>::null()));
let either: Value<i32> = Rc::new(RefCell::new(
(((!(*p1.borrow()).is_null()) || (!(*p2.borrow()).is_null())) as i32).clone(),
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/expr_as_bool_cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn main_0() -> i32 {
assert!(((*eq.borrow()) == 1));
assert!(((*lt.borrow()) == 0));
assert!(((*neq.borrow()) == 0));
let p1: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal("hi")));
let p1: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal(b"hi")));
let p2: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::<u8>::null()));
let either: Value<i32> = Rc::new(RefCell::new(
(((!(*p1.borrow()).is_null()) || (!(*p2.borrow()).is_null())) as i32).clone(),
Expand Down
24 changes: 12 additions & 12 deletions tests/unit/out/refcount/fn_ptr_stdlib_compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,17 @@ fn main_0() -> i32 {
'loop_: while __do_while || (0 != 0) {
__do_while = false;
let stream: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new(
match Ptr::from_string_literal("rb").to_rust_string() {
match Ptr::from_string_literal(b"rb").to_rust_string() {
v if v == "rb" => std::fs::OpenOptions::new()
.read(true)
.open(Ptr::from_string_literal("/dev/zero").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/zero").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
v if v == "wb" => std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(Ptr::from_string_literal("/dev/zero").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/zero").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
_ => panic!("unsupported mode"),
Expand Down Expand Up @@ -131,17 +131,17 @@ fn main_0() -> i32 {
'loop_: while __do_while || (0 != 0) {
__do_while = false;
let stream: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new(
match Ptr::from_string_literal("rb").to_rust_string() {
match Ptr::from_string_literal(b"rb").to_rust_string() {
v if v == "rb" => std::fs::OpenOptions::new()
.read(true)
.open(Ptr::from_string_literal("/dev/zero").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/zero").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
v if v == "wb" => std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(Ptr::from_string_literal("/dev/zero").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/zero").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
_ => panic!("unsupported mode"),
Expand Down Expand Up @@ -241,17 +241,17 @@ fn main_0() -> i32 {
'loop_: while __do_while || (0 != 0) {
__do_while = false;
let stream: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new(
match Ptr::from_string_literal("wb").to_rust_string() {
match Ptr::from_string_literal(b"wb").to_rust_string() {
v if v == "rb" => std::fs::OpenOptions::new()
.read(true)
.open(Ptr::from_string_literal("/dev/null").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/null").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
v if v == "wb" => std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(Ptr::from_string_literal("/dev/null").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/null").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
_ => panic!("unsupported mode"),
Expand Down Expand Up @@ -285,17 +285,17 @@ fn main_0() -> i32 {
'loop_: while __do_while || (0 != 0) {
__do_while = false;
let stream: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new(
match Ptr::from_string_literal("wb").to_rust_string() {
match Ptr::from_string_literal(b"wb").to_rust_string() {
v if v == "rb" => std::fs::OpenOptions::new()
.read(true)
.open(Ptr::from_string_literal("/dev/null").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/null").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
v if v == "wb" => std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(Ptr::from_string_literal("/dev/null").to_rust_string())
.open(Ptr::from_string_literal(b"/dev/null").to_rust_string())
.ok()
.map_or(Ptr::null(), |f| Ptr::alloc(f)),
_ => panic!("unsupported mode"),
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/out/refcount/fopen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
let fname: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal("testfile.txt")));
let mode: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal("rb")));
let fname: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal(b"testfile.txt")));
let mode: Value<Ptr<u8>> = Rc::new(RefCell::new(Ptr::from_string_literal(b"rb")));
let file_ptr: Value<Ptr<::std::fs::File>> =
Rc::new(RefCell::new(match (*mode.borrow()).to_rust_string() {
v if v == "rb" => std::fs::OpenOptions::new()
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/out/refcount/global_pointers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ impl Clone for Entry {
impl ByteRepr for Entry {}
thread_local!(
pub static single_entry_0: Value<Entry> = Rc::new(RefCell::new(Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("alone"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"alone"))),
p: Rc::new(RefCell::new(Ptr::<i32>::null())),
}));
);
thread_local!(
pub static entries_1: Value<Box<[Entry]>> = Rc::new(RefCell::new(Box::new([
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("first"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"first"))),
p: Rc::new(RefCell::new(Ptr::<i32>::null())),
},
Entry {
name: Rc::new(RefCell::new(Ptr::from_string_literal("second"))),
name: Rc::new(RefCell::new(Ptr::from_string_literal(b"second"))),
p: Rc::new(RefCell::new(Ptr::<i32>::null())),
},
])));
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/out/refcount/iterators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub fn main() {
}
fn main_0() -> i32 {
let x: Value<Vec<u8>> = Rc::new(RefCell::new(
Ptr::from_string_literal("hello")
Ptr::from_string_literal(b"hello")
.to_c_string_iterator()
.chain(std::iter::once(0))
.collect::<Vec<u8>>(),
Expand Down
Loading
Loading