Skip to content

Commit 0d8eb7e

Browse files
committed
Add rules + tests for puts/fileno
1 parent 3729894 commit 0d8eb7e

5 files changed

Lines changed: 324 additions & 0 deletions

File tree

rules/stdio/ir_unsafe.json

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,169 @@
400400
"type": "i32"
401401
}
402402
},
403+
"f13": {
404+
"body": [
405+
{
406+
"text": "let bytes = "
407+
},
408+
{
409+
"method_call": {
410+
"receiver": [
411+
{
412+
"text": "std::ffi::CStr::from_ptr("
413+
},
414+
{
415+
"placeholder": {
416+
"arg": 0,
417+
"access": "read"
418+
}
419+
},
420+
{
421+
"text": " as *const i8)"
422+
}
423+
],
424+
"body": [
425+
{
426+
"text": ".to_bytes()"
427+
}
428+
]
429+
}
430+
},
431+
{
432+
"text": ";\n let stdout = libcc2rs::cout_unsafe();\n let r1 = "
433+
},
434+
{
435+
"method_call": {
436+
"receiver": [
437+
{
438+
"text": "(*stdout)"
439+
}
440+
],
441+
"body": [
442+
{
443+
"text": ".write_all(bytes)"
444+
}
445+
]
446+
}
447+
},
448+
{
449+
"text": ";\n let r2 = "
450+
},
451+
{
452+
"method_call": {
453+
"receiver": [
454+
{
455+
"text": "(*stdout)"
456+
}
457+
],
458+
"body": [
459+
{
460+
"text": ".write_all(b\"\\n\")"
461+
}
462+
]
463+
}
464+
},
465+
{
466+
"text": ";\n if "
467+
},
468+
{
469+
"method_call": {
470+
"receiver": [
471+
{
472+
"text": "r1"
473+
}
474+
],
475+
"body": [
476+
{
477+
"text": ".is_ok()"
478+
}
479+
]
480+
}
481+
},
482+
{
483+
"text": " && "
484+
},
485+
{
486+
"method_call": {
487+
"receiver": [
488+
{
489+
"text": "r2"
490+
}
491+
],
492+
"body": [
493+
{
494+
"text": ".is_ok()"
495+
}
496+
]
497+
}
498+
},
499+
{
500+
"text": " { 0 } else { -1 }"
501+
}
502+
],
503+
"multi_statement": true,
504+
"params": {
505+
"a0": {
506+
"type": "*const u8",
507+
"is_unsafe_pointer": true
508+
}
509+
},
510+
"return_type": {
511+
"type": "i32"
512+
}
513+
},
514+
"f14": {
515+
"body": [
516+
{
517+
"text": "if "
518+
},
519+
{
520+
"placeholder": {
521+
"arg": 0,
522+
"access": "read"
523+
}
524+
},
525+
{
526+
"text": " == libcc2rs::cin_unsafe() {\n 0\n } else if "
527+
},
528+
{
529+
"placeholder": {
530+
"arg": 0,
531+
"access": "read"
532+
}
533+
},
534+
{
535+
"text": " == libcc2rs::cout_unsafe() {\n 1\n } else if "
536+
},
537+
{
538+
"placeholder": {
539+
"arg": 0,
540+
"access": "read"
541+
}
542+
},
543+
{
544+
"text": " == libcc2rs::cerr_unsafe() {\n 2\n } else {\n ::std::os::fd::AsRawFd::as_raw_fd(&*"
545+
},
546+
{
547+
"placeholder": {
548+
"arg": 0,
549+
"access": "read"
550+
}
551+
},
552+
{
553+
"text": ")\n }"
554+
}
555+
],
556+
"params": {
557+
"a0": {
558+
"type": "*mut ::std::fs::File",
559+
"is_unsafe_pointer": true
560+
}
561+
},
562+
"return_type": {
563+
"type": "i32"
564+
}
565+
},
403566
"f2": {
404567
"body": [
405568
{

rules/stdio/src.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,7 @@ FILE *f10() { return stdin; }
3636
int f11(int c, FILE *stream) { return fputc(c, stream); }
3737

3838
int f12(const char *s, FILE *stream) { return fputs(s, stream); }
39+
40+
int f13(const char *s) { return puts(s); }
41+
42+
int f14(FILE *stream) { return fileno(stream); }

rules/stdio/tgt_unsafe.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,23 @@ unsafe fn f12(a0: *const u8, a1: *mut ::std::fs::File) -> i32 {
120120
Err(_) => -1,
121121
}
122122
}
123+
124+
unsafe fn f13(a0: *const u8) -> i32 {
125+
let bytes = std::ffi::CStr::from_ptr(a0 as *const i8).to_bytes();
126+
let stdout = libcc2rs::cout_unsafe();
127+
let r1 = (*stdout).write_all(bytes);
128+
let r2 = (*stdout).write_all(b"\n");
129+
if r1.is_ok() && r2.is_ok() { 0 } else { -1 }
130+
}
131+
132+
unsafe fn f14(a0: *mut ::std::fs::File) -> i32 {
133+
if a0 == libcc2rs::cin_unsafe() {
134+
0
135+
} else if a0 == libcc2rs::cout_unsafe() {
136+
1
137+
} else if a0 == libcc2rs::cerr_unsafe() {
138+
2
139+
} else {
140+
::std::os::fd::AsRawFd::as_raw_fd(&*a0)
141+
}
142+
}

tests/unit/out/unsafe/stdio.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,122 @@ pub unsafe fn test_fputs_1() {
6565
Err(_) => -1,
6666
};
6767
}
68+
pub unsafe fn test_puts_2() {
69+
{
70+
let bytes = std::ffi::CStr::from_ptr(
71+
(b"puts hello\0".as_ptr().cast_mut()).cast_const() as *const i8
72+
)
73+
.to_bytes();
74+
let stdout = libcc2rs::cout_unsafe();
75+
let r1 = (*stdout).write_all(bytes);
76+
let r2 = (*stdout).write_all(b"\n");
77+
if r1.is_ok() && r2.is_ok() {
78+
0
79+
} else {
80+
-1
81+
}
82+
};
83+
let mut s: *const u8 = (b"puts variable\0".as_ptr().cast_mut()).cast_const();
84+
{
85+
let bytes = std::ffi::CStr::from_ptr(s as *const i8).to_bytes();
86+
let stdout = libcc2rs::cout_unsafe();
87+
let r1 = (*stdout).write_all(bytes);
88+
let r2 = (*stdout).write_all(b"\n");
89+
if r1.is_ok() && r2.is_ok() {
90+
0
91+
} else {
92+
-1
93+
}
94+
};
95+
}
96+
pub unsafe fn test_fileno_3() {
97+
assert!(
98+
((((if libcc2rs::cin_unsafe() == libcc2rs::cin_unsafe() {
99+
0
100+
} else if libcc2rs::cin_unsafe() == libcc2rs::cout_unsafe() {
101+
1
102+
} else if libcc2rs::cin_unsafe() == libcc2rs::cerr_unsafe() {
103+
2
104+
} else {
105+
::std::os::fd::AsRawFd::as_raw_fd(&*libcc2rs::cin_unsafe())
106+
}) == (0)) as i32)
107+
!= 0)
108+
);
109+
assert!(
110+
((((if libcc2rs::cout_unsafe() == libcc2rs::cin_unsafe() {
111+
0
112+
} else if libcc2rs::cout_unsafe() == libcc2rs::cout_unsafe() {
113+
1
114+
} else if libcc2rs::cout_unsafe() == libcc2rs::cerr_unsafe() {
115+
2
116+
} else {
117+
::std::os::fd::AsRawFd::as_raw_fd(&*libcc2rs::cout_unsafe())
118+
}) == (1)) as i32)
119+
!= 0)
120+
);
121+
assert!(
122+
((((if libcc2rs::cerr_unsafe() == libcc2rs::cin_unsafe() {
123+
0
124+
} else if libcc2rs::cerr_unsafe() == libcc2rs::cout_unsafe() {
125+
1
126+
} else if libcc2rs::cerr_unsafe() == libcc2rs::cerr_unsafe() {
127+
2
128+
} else {
129+
::std::os::fd::AsRawFd::as_raw_fd(&*libcc2rs::cerr_unsafe())
130+
}) == (2)) as i32)
131+
!= 0)
132+
);
133+
let mut fp: *mut ::std::fs::File =
134+
match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8)
135+
.to_str()
136+
.expect("invalid c-string")
137+
{
138+
v if v == "rb" => std::fs::OpenOptions::new()
139+
.read(true)
140+
.open(
141+
std::ffi::CStr::from_ptr(
142+
(b"/tmp/cpp2rust_fileno_test.tmp\0".as_ptr().cast_mut()).cast_const()
143+
as *const i8,
144+
)
145+
.to_str()
146+
.expect("invalid c-string"),
147+
)
148+
.ok()
149+
.map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))),
150+
v if v == "wb" => std::fs::OpenOptions::new()
151+
.write(true)
152+
.create(true)
153+
.truncate(true)
154+
.open(
155+
std::ffi::CStr::from_ptr(
156+
(b"/tmp/cpp2rust_fileno_test.tmp\0".as_ptr().cast_mut()).cast_const()
157+
as *const i8,
158+
)
159+
.to_str()
160+
.expect("invalid c-string"),
161+
)
162+
.ok()
163+
.map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))),
164+
_ => panic!("unsupported mode"),
165+
};
166+
assert!((((!((fp).is_null())) as i32) != 0));
167+
assert!(
168+
((((if fp == libcc2rs::cin_unsafe() {
169+
0
170+
} else if fp == libcc2rs::cout_unsafe() {
171+
1
172+
} else if fp == libcc2rs::cerr_unsafe() {
173+
2
174+
} else {
175+
::std::os::fd::AsRawFd::as_raw_fd(&*fp)
176+
}) > (2)) as i32)
177+
!= 0)
178+
);
179+
{
180+
Box::from_raw(fp);
181+
0
182+
};
183+
}
68184
pub fn main() {
69185
unsafe {
70186
std::process::exit(main_0() as i32);
@@ -73,5 +189,7 @@ pub fn main() {
73189
unsafe fn main_0() -> i32 {
74190
(unsafe { test_fputc_0() });
75191
(unsafe { test_fputs_1() });
192+
(unsafe { test_puts_2() });
193+
(unsafe { test_fileno_3() });
76194
return 0;
77195
}

tests/unit/stdio.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// no-compile: refcount
2+
#include <assert.h>
23
#include <stdio.h>
34

45
static void test_fputc(void) {
@@ -18,8 +19,26 @@ static void test_fputs(void) {
1819
fputc('\n', stdout);
1920
}
2021

22+
static void test_puts(void) {
23+
puts("puts hello");
24+
const char *s = "puts variable";
25+
puts(s);
26+
}
27+
28+
static void test_fileno(void) {
29+
assert(fileno(stdin) == 0);
30+
assert(fileno(stdout) == 1);
31+
assert(fileno(stderr) == 2);
32+
FILE *fp = fopen("/tmp/cpp2rust_fileno_test.tmp", "wb");
33+
assert(fp != NULL);
34+
assert(fileno(fp) > 2);
35+
fclose(fp);
36+
}
37+
2138
int main(void) {
2239
test_fputc();
2340
test_fputs();
41+
test_puts();
42+
test_fileno();
2443
return 0;
2544
}

0 commit comments

Comments
 (0)