@@ -16,127 +16,65 @@ extern crate libc;
16
16
17
17
use libc:: { c_char, c_double, c_int, c_long, c_longlong} ;
18
18
use std:: ffi:: VaList ;
19
- use std:: slice;
20
- use std:: ffi:: CStr ;
19
+ use std:: ffi:: { CString , CStr } ;
21
20
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
+ }
32
27
}
33
28
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
43
33
}
44
34
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
49
41
}
50
42
51
43
#[ 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
106
53
}
107
54
108
55
#[ 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
112
65
}
113
66
114
67
#[ 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
136
78
}
137
- }
138
-
139
- ap. copy ( |ap| {
140
- compare_answers ( & slice[ skip_n..] , ap)
141
79
} )
142
80
}
0 commit comments