Skip to content

Commit 3729894

Browse files
committed
Add rules + tests for fputc/fputs
1 parent a54bbfd commit 3729894

5 files changed

Lines changed: 257 additions & 0 deletions

File tree

rules/stdio/ir_unsafe.json

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,142 @@
264264
"is_unsafe_pointer": true
265265
}
266266
},
267+
"f11": {
268+
"body": [
269+
{
270+
"text": "match "
271+
},
272+
{
273+
"method_call": {
274+
"receiver": [
275+
{
276+
"text": "(*"
277+
},
278+
{
279+
"placeholder": {
280+
"arg": 1,
281+
"access": "write"
282+
}
283+
},
284+
{
285+
"text": ")"
286+
}
287+
],
288+
"body": [
289+
{
290+
"text": ".write_all(&["
291+
},
292+
{
293+
"placeholder": {
294+
"arg": 0,
295+
"access": "read"
296+
}
297+
},
298+
{
299+
"text": " as u8])"
300+
}
301+
]
302+
}
303+
},
304+
{
305+
"text": " {\n Ok(()) => "
306+
},
307+
{
308+
"placeholder": {
309+
"arg": 0,
310+
"access": "read"
311+
}
312+
},
313+
{
314+
"text": " & 0xff,\n Err(_) => -1,\n }"
315+
}
316+
],
317+
"params": {
318+
"a0": {
319+
"type": "i32"
320+
},
321+
"a1": {
322+
"type": "*mut ::std::fs::File",
323+
"is_unsafe_pointer": true
324+
}
325+
},
326+
"return_type": {
327+
"type": "i32"
328+
}
329+
},
330+
"f12": {
331+
"body": [
332+
{
333+
"text": "let bytes = "
334+
},
335+
{
336+
"method_call": {
337+
"receiver": [
338+
{
339+
"text": "std::ffi::CStr::from_ptr("
340+
},
341+
{
342+
"placeholder": {
343+
"arg": 0,
344+
"access": "read"
345+
}
346+
},
347+
{
348+
"text": " as *const i8)"
349+
}
350+
],
351+
"body": [
352+
{
353+
"text": ".to_bytes()"
354+
}
355+
]
356+
}
357+
},
358+
{
359+
"text": ";\n match "
360+
},
361+
{
362+
"method_call": {
363+
"receiver": [
364+
{
365+
"text": "(*"
366+
},
367+
{
368+
"placeholder": {
369+
"arg": 1,
370+
"access": "write"
371+
}
372+
},
373+
{
374+
"text": ")"
375+
}
376+
],
377+
"body": [
378+
{
379+
"text": ".write_all(bytes)"
380+
}
381+
]
382+
}
383+
},
384+
{
385+
"text": " {\n Ok(()) => 0,\n Err(_) => -1,\n }"
386+
}
387+
],
388+
"multi_statement": true,
389+
"params": {
390+
"a0": {
391+
"type": "*const u8",
392+
"is_unsafe_pointer": true
393+
},
394+
"a1": {
395+
"type": "*mut ::std::fs::File",
396+
"is_unsafe_pointer": true
397+
}
398+
},
399+
"return_type": {
400+
"type": "i32"
401+
}
402+
},
267403
"f2": {
268404
"body": [
269405
{

rules/stdio/src.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ FILE *f8() { return stdout; }
3232
FILE *f9() { return stderr; }
3333

3434
FILE *f10() { return stdin; }
35+
36+
int f11(int c, FILE *stream) { return fputc(c, stream); }
37+
38+
int f12(const char *s, FILE *stream) { return fputs(s, stream); }

rules/stdio/tgt_unsafe.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,18 @@ unsafe fn f9() -> *mut ::std::fs::File {
105105
unsafe fn f10() -> *mut ::std::fs::File {
106106
libcc2rs::cin_unsafe()
107107
}
108+
109+
unsafe fn f11(a0: i32, a1: *mut ::std::fs::File) -> i32 {
110+
match (*a1).write_all(&[a0 as u8]) {
111+
Ok(()) => a0 & 0xff,
112+
Err(_) => -1,
113+
}
114+
}
115+
116+
unsafe fn f12(a0: *const u8, a1: *mut ::std::fs::File) -> i32 {
117+
let bytes = std::ffi::CStr::from_ptr(a0 as *const i8).to_bytes();
118+
match (*a1).write_all(bytes) {
119+
Ok(()) => 0,
120+
Err(_) => -1,
121+
}
122+
}

tests/unit/out/unsafe/stdio.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub unsafe fn test_fputc_0() {
10+
match (*libcc2rs::cout_unsafe()).write_all(&[('H' as i32) as u8]) {
11+
Ok(()) => ('H' as i32) & 0xff,
12+
Err(_) => -1,
13+
};
14+
match (*libcc2rs::cout_unsafe()).write_all(&[('i' as i32) as u8]) {
15+
Ok(()) => ('i' as i32) & 0xff,
16+
Err(_) => -1,
17+
};
18+
match (*libcc2rs::cout_unsafe()).write_all(&[('\n' as i32) as u8]) {
19+
Ok(()) => ('\n' as i32) & 0xff,
20+
Err(_) => -1,
21+
};
22+
}
23+
pub unsafe fn test_fputs_1() {
24+
{
25+
let bytes =
26+
std::ffi::CStr::from_ptr((b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8)
27+
.to_bytes();
28+
match (*libcc2rs::cout_unsafe()).write_all(bytes) {
29+
Ok(()) => 0,
30+
Err(_) => -1,
31+
}
32+
};
33+
match (*libcc2rs::cout_unsafe()).write_all(&[('\n' as i32) as u8]) {
34+
Ok(()) => ('\n' as i32) & 0xff,
35+
Err(_) => -1,
36+
};
37+
let mut s: *const u8 = (b"from variable\0".as_ptr().cast_mut()).cast_const();
38+
{
39+
let bytes = std::ffi::CStr::from_ptr(s as *const i8).to_bytes();
40+
match (*libcc2rs::cout_unsafe()).write_all(bytes) {
41+
Ok(()) => 0,
42+
Err(_) => -1,
43+
}
44+
};
45+
match (*libcc2rs::cout_unsafe()).write_all(&[('\n' as i32) as u8]) {
46+
Ok(()) => ('\n' as i32) & 0xff,
47+
Err(_) => -1,
48+
};
49+
let mut buf: [u8; 4] = [
50+
(('b' as i32) as u8),
51+
(('u' as i32) as u8),
52+
(('f' as i32) as u8),
53+
(('\0' as i32) as u8),
54+
];
55+
{
56+
let bytes =
57+
std::ffi::CStr::from_ptr((buf.as_mut_ptr()).cast_const() as *const i8).to_bytes();
58+
match (*libcc2rs::cout_unsafe()).write_all(bytes) {
59+
Ok(()) => 0,
60+
Err(_) => -1,
61+
}
62+
};
63+
match (*libcc2rs::cout_unsafe()).write_all(&[('\n' as i32) as u8]) {
64+
Ok(()) => ('\n' as i32) & 0xff,
65+
Err(_) => -1,
66+
};
67+
}
68+
pub fn main() {
69+
unsafe {
70+
std::process::exit(main_0() as i32);
71+
}
72+
}
73+
unsafe fn main_0() -> i32 {
74+
(unsafe { test_fputc_0() });
75+
(unsafe { test_fputs_1() });
76+
return 0;
77+
}

tests/unit/stdio.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// no-compile: refcount
2+
#include <stdio.h>
3+
4+
static void test_fputc(void) {
5+
fputc('H', stdout);
6+
fputc('i', stdout);
7+
fputc('\n', stdout);
8+
}
9+
10+
static void test_fputs(void) {
11+
fputs("hello", stdout);
12+
fputc('\n', stdout);
13+
const char *s = "from variable";
14+
fputs(s, stdout);
15+
fputc('\n', stdout);
16+
char buf[] = {'b', 'u', 'f', '\0'};
17+
fputs(buf, stdout);
18+
fputc('\n', stdout);
19+
}
20+
21+
int main(void) {
22+
test_fputc();
23+
test_fputs();
24+
return 0;
25+
}

0 commit comments

Comments
 (0)