Skip to content

Commit ed03081

Browse files
authored
Add translation rule for stdin (#85)
1 parent 2ef0a51 commit ed03081

9 files changed

Lines changed: 64 additions & 0 deletions

File tree

libcc2rs/src/io.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
77
use std::rc::Rc;
88

99
thread_local! {
10+
static SAFE_STDIN: Value<std::fs::File> = Rc::new(RefCell::new(std::fs::File::from(
11+
std::io::stdin().as_fd().try_clone_to_owned().unwrap(),
12+
)));
1013
static SAFE_STDOUT: Value<std::fs::File> = Rc::new(RefCell::new(std::fs::File::from(
1114
std::io::stdout().as_fd().try_clone_to_owned().unwrap(),
1215
)));
1316
static SAFE_STDERR: Value<std::fs::File> = Rc::new(RefCell::new(std::fs::File::from(
1417
std::io::stderr().as_fd().try_clone_to_owned().unwrap(),
1518
)));
19+
static UNSAFE_STDIN: UnsafeCell<std::fs::File> = unsafe {
20+
UnsafeCell::new(
21+
std::fs::File::from_raw_fd(
22+
std::io::stdin()
23+
.as_fd()
24+
.try_clone_to_owned()
25+
.unwrap()
26+
.into_raw_fd(),
27+
))
28+
};
1629
static UNSAFE_STDOUT: UnsafeCell<std::fs::File> = unsafe {
1730
UnsafeCell::new(
1831
std::fs::File::from_raw_fd(
@@ -35,6 +48,10 @@ thread_local! {
3548
};
3649
}
3750

51+
pub fn cin() -> Ptr<std::fs::File> {
52+
SAFE_STDIN.with(AsPointer::as_pointer)
53+
}
54+
3855
pub fn cout() -> Ptr<std::fs::File> {
3956
SAFE_STDOUT.with(AsPointer::as_pointer)
4057
}
@@ -43,6 +60,14 @@ pub fn cerr() -> Ptr<std::fs::File> {
4360
SAFE_STDERR.with(AsPointer::as_pointer)
4461
}
4562

63+
/// # Safety
64+
///
65+
/// The caller must ensure that the returned pointer is not used after the
66+
// thread finishes.
67+
pub unsafe fn cin_unsafe() -> *mut std::fs::File {
68+
UNSAFE_STDIN.with(UnsafeCell::get)
69+
}
70+
4671
/// # Safety
4772
///
4873
/// The caller must ensure that the returned pointer is not used after the

rules/stdio/ir_refcount.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,17 @@
202202
"is_refcount_pointer": true
203203
}
204204
},
205+
"f10": {
206+
"body": [
207+
{
208+
"text": "libcc2rs::cin()"
209+
}
210+
],
211+
"return_type": {
212+
"type": "Ptr<::std::fs::File>",
213+
"is_refcount_pointer": true
214+
}
215+
},
205216
"f2": {
206217
"body": [
207218
{

rules/stdio/ir_unsafe.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,17 @@
253253
"is_unsafe_pointer": true
254254
}
255255
},
256+
"f10": {
257+
"body": [
258+
{
259+
"text": "libcc2rs::cin_unsafe()"
260+
}
261+
],
262+
"return_type": {
263+
"type": "*mut ::std::fs::File",
264+
"is_unsafe_pointer": true
265+
}
266+
},
256267
"f2": {
257268
"body": [
258269
{

rules/stdio/src.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ int f7(FILE *stream) { return fflush(stream); }
3030
FILE *f8() { return stdout; }
3131

3232
FILE *f9() { return stderr; }
33+
34+
FILE *f10() { return stdin; }

rules/stdio/tgt_refcount.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,7 @@ fn f8() -> Ptr<::std::fs::File> {
125125
fn f9() -> Ptr<::std::fs::File> {
126126
libcc2rs::cerr()
127127
}
128+
129+
fn f10() -> Ptr<::std::fs::File> {
130+
libcc2rs::cin()
131+
}

rules/stdio/tgt_unsafe.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,7 @@ unsafe fn f8() -> *mut ::std::fs::File {
130130
unsafe fn f9() -> *mut ::std::fs::File {
131131
libcc2rs::cerr_unsafe()
132132
}
133+
134+
unsafe fn f10() -> *mut ::std::fs::File {
135+
libcc2rs::cin_unsafe()
136+
}

tests/unit/out/refcount/printfs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ fn main_0() -> i32 {
2626
println!("{}", Ptr::from_string_literal("fprintf stdout"));
2727
println!("{} {} {}", 1, 2_u32, 3_i64);
2828
print!("hello world");
29+
let in_: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new((libcc2rs::cin()).clone()));
30+
assert!(!((*in_.borrow()).is_null()));
2931
println!("{}", Ptr::from_string_literal("printf"));
3032
print!("hello world");
3133
let s: Value<Vec<u8>> = Rc::new(RefCell::new(

tests/unit/out/unsafe/printfs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ unsafe fn main_0() -> i32 {
3434
);
3535
printf(b"%d %u %ld\n\0".as_ptr() as *const i8, 1, 2_u32, 3_i64);
3636
printf(b"hello world\0".as_ptr() as *const i8);
37+
let mut in_: *mut ::std::fs::File = libcc2rs::cin_unsafe();
38+
assert!(!((in_).is_null()));
3739
printf(b"%s\n\0".as_ptr() as *const i8, b"printf\0".as_ptr());
3840
printf(b"hello world\0".as_ptr() as *const i8);
3941
let mut s: Vec<u8> = {

tests/unit/printfs.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) 2022-present INESC-ID.
22
// Distributed under the MIT license that can be found in the LICENSE file.
33

4+
#include <cassert>
45
#include <cstdio>
56
#include <string>
67

@@ -12,6 +13,8 @@ int main() {
1213
fprintf(stdout, "%s\n", "fprintf stdout");
1314
fprintf(stdout, "%d %u %ld\n", 1, 2U, 3L);
1415
fprintf(stdout, "hello world");
16+
FILE *in = stdin;
17+
assert(in != NULL);
1518
printf("%s\n", "printf");
1619
printf("hello world");
1720
std::string s = "a string";

0 commit comments

Comments
 (0)