@@ -16,127 +16,65 @@ extern crate libc;
1616
1717use libc:: { c_char, c_double, c_int, c_long, c_longlong} ;
1818use std:: ffi:: VaList ;
19- use std:: slice;
20- use std:: ffi:: CStr ;
19+ use std:: ffi:: { CString , CStr } ;
2120
22- #[ repr( C ) ]
23- #[ derive( Clone , Copy , Debug ) ]
24- pub enum AnswerType {
25- Double ,
26- Long ,
27- LongLong ,
28- Int ,
29- Byte ,
30- CStr ,
31- Skip ,
21+ macro_rules! continue_if {
22+ ( $cond: expr) => {
23+ if !( $cond) {
24+ return 0xff ;
25+ }
26+ }
3227}
3328
34- #[ repr( C ) ]
35- pub union AnswerData {
36- pub double : c_double ,
37- pub long : c_long ,
38- pub longlong : c_longlong ,
39- pub int : c_int ,
40- pub byte : c_char ,
41- pub cstr : * const c_char ,
42- pub skip_ty : AnswerType ,
29+ unsafe fn compare_c_str ( ptr : * const c_char , val : & str ) -> bool {
30+ let cstr0 = CStr :: from_ptr ( ptr) ;
31+ let cstr1 = CString :: new ( val) . unwrap ( ) ;
32+ & * cstr1 == cstr0
4333}
4434
45- #[ repr( C ) ]
46- pub struct Answer {
47- tag : AnswerType ,
48- data : AnswerData ,
35+ #[ no_mangle]
36+ pub unsafe extern "C" fn check_list_0 ( mut ap : VaList ) -> usize {
37+ continue_if ! ( ap. arg:: <c_longlong>( ) == 1 ) ;
38+ continue_if ! ( ap. arg:: <c_int>( ) == 2 ) ;
39+ continue_if ! ( ap. arg:: <c_longlong>( ) == 3 ) ;
40+ 0
4941}
5042
5143#[ no_mangle]
52- pub unsafe fn compare_answers ( answers : & [ Answer ] , mut ap : VaList ) -> usize {
53- for ( i, answer) in answers. iter ( ) . enumerate ( ) {
54- match answer {
55- Answer { tag : AnswerType :: Double , data : AnswerData { double : d } } => {
56- let tmp = ap. arg :: < c_double > ( ) ;
57- if d. floor ( ) != tmp. floor ( ) {
58- println ! ( "Double: {} != {}" , d, tmp) ;
59- return i + 1 ;
60- }
61- }
62- Answer { tag : AnswerType :: Long , data : AnswerData { long : l } } => {
63- let tmp = ap. arg :: < c_long > ( ) ;
64- if * l != tmp {
65- println ! ( "Long: {} != {}" , l, tmp) ;
66- return i + 1 ;
67- }
68- }
69- Answer { tag : AnswerType :: LongLong , data : AnswerData { longlong : l } } => {
70- let tmp = ap. arg :: < c_longlong > ( ) ;
71- if * l != tmp {
72- println ! ( "Long Long: {} != {}" , l, tmp) ;
73- return i + 1 ;
74- }
75- }
76- Answer { tag : AnswerType :: Int , data : AnswerData { int : n } } => {
77- let tmp = ap. arg :: < c_int > ( ) ;
78- if * n != tmp {
79- println ! ( "Int: {} != {}" , n, tmp) ;
80- return i + 1 ;
81- }
82- }
83- Answer { tag : AnswerType :: Byte , data : AnswerData { byte : b } } => {
84- let tmp = ap. arg :: < c_char > ( ) ;
85- if * b != tmp {
86- println ! ( "Byte: {} != {}" , b, tmp) ;
87- return i + 1 ;
88- }
89- }
90- Answer { tag : AnswerType :: CStr , data : AnswerData { cstr : c0 } } => {
91- let c1 = ap. arg :: < * const c_char > ( ) ;
92- let cstr0 = CStr :: from_ptr ( * c0) ;
93- let cstr1 = CStr :: from_ptr ( c1) ;
94- if cstr0 != cstr1 {
95- println ! ( "C String: {:?} != {:?}" , cstr0, cstr1) ;
96- return i + 1 ;
97- }
98- }
99- _ => {
100- println ! ( "Unknown type!" ) ;
101- return i + 1 ;
102- }
103- }
104- }
105- return 0 ;
44+ pub unsafe extern "C" fn check_list_1 ( mut ap : VaList ) -> usize {
45+ continue_if ! ( ap. arg:: <c_int>( ) == -1 ) ;
46+ continue_if ! ( ap. arg:: <c_char>( ) == 'A' as c_char) ;
47+ continue_if ! ( ap. arg:: <c_char>( ) == '4' as c_char) ;
48+ continue_if ! ( ap. arg:: <c_char>( ) == ';' as c_char) ;
49+ continue_if ! ( ap. arg:: <c_int>( ) == 0x32 ) ;
50+ continue_if ! ( ap. arg:: <c_int>( ) == 0x10000001 ) ;
51+ continue_if ! ( compare_c_str( ap. arg:: <* const c_char>( ) , "Valid!" ) ) ;
52+ 0
10653}
10754
10855#[ no_mangle]
109- pub unsafe extern "C" fn check_rust ( argc : usize , answers : * const Answer , ap : VaList ) -> usize {
110- let slice = slice:: from_raw_parts ( answers, argc) ;
111- compare_answers ( slice, ap)
56+ pub unsafe extern "C" fn check_list_2 ( mut ap : VaList ) -> usize {
57+ continue_if ! ( ap. arg:: <c_double>( ) . floor( ) == 3.14f64 . floor( ) ) ;
58+ continue_if ! ( ap. arg:: <c_long>( ) == 12 ) ;
59+ continue_if ! ( ap. arg:: <c_char>( ) == 'a' as c_char) ;
60+ continue_if ! ( ap. arg:: <c_double>( ) . floor( ) == 6.18f64 . floor( ) ) ;
61+ continue_if ! ( compare_c_str( ap. arg:: <* const c_char>( ) , "Hello" ) ) ;
62+ continue_if ! ( ap. arg:: <c_int>( ) == 42 ) ;
63+ continue_if ! ( compare_c_str( ap. arg:: <* const c_char>( ) , "World" ) ) ;
64+ 0
11265}
11366
11467#[ no_mangle]
115- pub unsafe extern "C" fn check_rust_copy ( argc : usize , answers : * const Answer ,
116- mut ap : VaList ) -> usize {
117- let slice = slice:: from_raw_parts ( answers, argc) ;
118- let mut skip_n = 0 ;
119- for ( i, answer) in slice. iter ( ) . enumerate ( ) {
120- match answer {
121- Answer { tag : AnswerType :: Skip , data : AnswerData { skip_ty } } => {
122- match skip_ty {
123- AnswerType :: Double => { ap. arg :: < c_double > ( ) ; }
124- AnswerType :: Long => { ap. arg :: < c_long > ( ) ; }
125- AnswerType :: LongLong => { ap. arg :: < c_longlong > ( ) ; }
126- AnswerType :: Int => { ap. arg :: < c_int > ( ) ; }
127- AnswerType :: Byte => { ap. arg :: < c_char > ( ) ; }
128- AnswerType :: CStr => { ap. arg :: < * const c_char > ( ) ; }
129- _ => { return i; }
130- } ;
131- }
132- _ => {
133- skip_n = i;
134- break ;
135- }
68+ pub unsafe extern "C" fn check_list_copy_0 ( mut ap : VaList ) -> usize {
69+ continue_if ! ( ap. arg:: <c_double>( ) . floor( ) == 6.28f64 . floor( ) ) ;
70+ continue_if ! ( ap. arg:: <c_int>( ) == 16 ) ;
71+ continue_if ! ( ap. arg:: <c_char>( ) == 'A' as c_char) ;
72+ continue_if ! ( compare_c_str( ap. arg:: <* const c_char>( ) , "Skip Me!" ) ) ;
73+ ap. copy ( |mut ap| {
74+ if compare_c_str ( ap. arg :: < * const c_char > ( ) , "Correct" ) {
75+ 0
76+ } else {
77+ 0xff
13678 }
137- }
138-
139- ap. copy ( |ap| {
140- compare_answers ( & slice[ skip_n..] , ap)
14179 } )
14280}
0 commit comments