@@ -3,6 +3,7 @@ use proc_macro2::Span;
3
3
use quote:: ToTokens ;
4
4
use syn:: spanned:: Spanned ;
5
5
6
+ use crate :: cdecl:: Constness ;
6
7
use crate :: ffi_items:: FfiItems ;
7
8
use crate :: translator:: Translator ;
8
9
use crate :: {
@@ -84,7 +85,7 @@ impl TestTemplate {
84
85
& mut self ,
85
86
helper : & TranslateHelper ,
86
87
) -> Result < ( ) , TranslationError > {
87
- for constant in helper. ffi_items . constants ( ) {
88
+ for constant in helper. filtered_ffi_items . constants ( ) {
88
89
if let syn:: Type :: Ptr ( ptr) = & constant. ty
89
90
&& let syn:: Type :: Path ( path) = & * ptr. elem
90
91
&& path. path . segments . last ( ) . unwrap ( ) . ident == "c_char"
@@ -122,7 +123,7 @@ impl TestTemplate {
122
123
& mut self ,
123
124
helper : & TranslateHelper ,
124
125
) -> Result < ( ) , TranslationError > {
125
- for alias in helper. ffi_items . aliases ( ) {
126
+ for alias in helper. filtered_ffi_items . aliases ( ) {
126
127
let item = TestSizeAlign {
127
128
test_name : size_align_test_ident ( alias. ident ( ) ) ,
128
129
id : alias. ident ( ) . into ( ) ,
@@ -132,7 +133,7 @@ impl TestTemplate {
132
133
self . size_align_tests . push ( item. clone ( ) ) ;
133
134
self . test_idents . push ( item. test_name ) ;
134
135
}
135
- for struct_ in helper. ffi_items . structs ( ) {
136
+ for struct_ in helper. filtered_ffi_items . structs ( ) {
136
137
let item = TestSizeAlign {
137
138
test_name : size_align_test_ident ( struct_. ident ( ) ) ,
138
139
id : struct_. ident ( ) . into ( ) ,
@@ -142,7 +143,7 @@ impl TestTemplate {
142
143
self . size_align_tests . push ( item. clone ( ) ) ;
143
144
self . test_idents . push ( item. test_name ) ;
144
145
}
145
- for union_ in helper. ffi_items . unions ( ) {
146
+ for union_ in helper. filtered_ffi_items . unions ( ) {
146
147
let item = TestSizeAlign {
147
148
test_name : size_align_test_ident ( union_. ident ( ) ) ,
148
149
id : union_. ident ( ) . into ( ) ,
@@ -163,7 +164,7 @@ impl TestTemplate {
163
164
& mut self ,
164
165
helper : & TranslateHelper ,
165
166
) -> Result < ( ) , TranslationError > {
166
- for alias in helper. ffi_items . aliases ( ) {
167
+ for alias in helper. filtered_ffi_items . aliases ( ) {
167
168
let should_skip_signededness_test = helper
168
169
. generator
169
170
. skip_signededness
@@ -195,7 +196,7 @@ impl TestTemplate {
195
196
let should_skip = |map_input| helper. generator . skips . iter ( ) . any ( |f| f ( & map_input) ) ;
196
197
197
198
let struct_fields = helper
198
- . ffi_items
199
+ . filtered_ffi_items
199
200
. structs ( )
200
201
. iter ( )
201
202
. flat_map ( |struct_| struct_. fields . iter ( ) . map ( move |field| ( struct_, field) ) )
@@ -211,7 +212,7 @@ impl TestTemplate {
211
212
)
212
213
} ) ;
213
214
let union_fields = helper
214
- . ffi_items
215
+ . filtered_ffi_items
215
216
. unions ( )
216
217
. iter ( )
217
218
. flat_map ( |union_| union_. fields . iter ( ) . map ( move |field| ( union_, field) ) )
@@ -249,15 +250,15 @@ impl TestTemplate {
249
250
& mut self ,
250
251
helper : & TranslateHelper ,
251
252
) -> Result < ( ) , TranslationError > {
252
- for alias in helper. ffi_items . aliases ( ) {
253
+ for alias in helper. filtered_ffi_items . aliases ( ) {
253
254
let c_ty = helper. c_type ( alias) ?;
254
255
self . add_roundtrip_test ( helper, alias. ident ( ) , & [ ] , & c_ty, true ) ;
255
256
}
256
- for struct_ in helper. ffi_items . structs ( ) {
257
+ for struct_ in helper. filtered_ffi_items . structs ( ) {
257
258
let c_ty = helper. c_type ( struct_) ?;
258
259
self . add_roundtrip_test ( helper, struct_. ident ( ) , & struct_. fields , & c_ty, false ) ;
259
260
}
260
- for union_ in helper. ffi_items . unions ( ) {
261
+ for union_ in helper. filtered_ffi_items . unions ( ) {
261
262
let c_ty = helper. c_type ( union_) ?;
262
263
self . add_roundtrip_test ( helper, union_. ident ( ) , & union_. fields , & c_ty, false ) ;
263
264
}
@@ -301,14 +302,14 @@ impl TestTemplate {
301
302
let should_skip = |map_input| helper. generator . skips . iter ( ) . any ( |f| f ( & map_input) ) ;
302
303
303
304
let struct_fields = helper
304
- . ffi_items
305
+ . filtered_ffi_items
305
306
. structs ( )
306
307
. iter ( )
307
308
. flat_map ( |s| s. fields . iter ( ) . map ( move |f| ( s, f) ) )
308
309
. filter ( |( s, f) | {
309
- !should_skip ( MapInput :: StructField ( s, f) )
310
- && ! should_skip ( MapInput :: StructFieldType ( s, f) )
311
- && f. public
310
+ !( should_skip ( MapInput :: StructField ( s, f) )
311
+ || should_skip ( MapInput :: StructFieldType ( s, f) )
312
+ || ! f. public )
312
313
} )
313
314
. map ( |( s, f) | {
314
315
(
@@ -330,14 +331,14 @@ impl TestTemplate {
330
331
)
331
332
} ) ;
332
333
let union_fields = helper
333
- . ffi_items
334
+ . filtered_ffi_items
334
335
. unions ( )
335
336
. iter ( )
336
337
. flat_map ( |u| u. fields . iter ( ) . map ( move |f| ( u, f) ) )
337
338
. filter ( |( u, f) | {
338
- !should_skip ( MapInput :: UnionField ( u, f) )
339
- && ! should_skip ( MapInput :: UnionFieldType ( u, f) )
340
- && f. public
339
+ !( should_skip ( MapInput :: UnionField ( u, f) )
340
+ || should_skip ( MapInput :: UnionFieldType ( u, f) )
341
+ || ! f. public )
341
342
} )
342
343
. map ( |( u, f) | {
343
344
(
@@ -487,6 +488,7 @@ fn roundtrip_test_ident(ident: &str) -> BoxStr {
487
488
488
489
/// Wrap methods that depend on both ffi items and the generator.
489
490
pub ( crate ) struct TranslateHelper < ' a > {
491
+ filtered_ffi_items : FfiItems ,
490
492
ffi_items : & ' a FfiItems ,
491
493
generator : & ' a TestGenerator ,
492
494
translator : Translator < ' a > ,
@@ -495,11 +497,52 @@ pub(crate) struct TranslateHelper<'a> {
495
497
impl < ' a > TranslateHelper < ' a > {
496
498
/// Create a new translation helper.
497
499
pub ( crate ) fn new ( ffi_items : & ' a FfiItems , generator : & ' a TestGenerator ) -> Self {
498
- Self {
500
+ let filtered_ffi_items = ffi_items. clone ( ) ;
501
+ let mut helper = Self {
502
+ filtered_ffi_items,
499
503
ffi_items,
500
504
generator,
501
505
translator : Translator :: new ( ffi_items, generator) ,
506
+ } ;
507
+ helper. filter_ffi_items ( ) ;
508
+
509
+ helper
510
+ }
511
+
512
+ /// Skips entire items such as structs, constants, and aliases from being tested.
513
+ ///
514
+ /// Does not skip specific tests or specific fields. If `skip_private` is true,
515
+ /// it will skip tests for all private items.
516
+ fn filter_ffi_items ( & mut self ) {
517
+ let verbose = self . generator . verbose_skip ;
518
+
519
+ macro_rules! filter {
520
+ ( $field: ident, $variant: ident, $label: literal) => { {
521
+ let skipped: Vec <_> = self
522
+ . filtered_ffi_items
523
+ . $field
524
+ . extract_if( .., |item| {
525
+ self . generator
526
+ . skips
527
+ . iter( )
528
+ . any( |f| f( & MapInput :: $variant( item) ) )
529
+ || ( self . generator. skip_private && !item. public)
530
+ } )
531
+ . collect( ) ;
532
+ if verbose {
533
+ skipped
534
+ . iter( )
535
+ . for_each( |item| eprintln!( "Skipping {} \" {}\" " , $label, item. ident( ) ) ) ;
536
+ }
537
+ } } ;
502
538
}
539
+
540
+ filter ! ( aliases, Alias , "alias" ) ;
541
+ filter ! ( constants, Const , "const" ) ;
542
+ filter ! ( structs, Struct , "struct" ) ;
543
+ filter ! ( unions, Union , "union" ) ;
544
+ filter ! ( foreign_functions, Fn , "fn" ) ;
545
+ filter ! ( foreign_statics, Static , "static" ) ;
503
546
}
504
547
505
548
/// Returns the equivalent C/Cpp identifier of the Rust item.
@@ -520,9 +563,12 @@ impl<'a> TranslateHelper<'a> {
520
563
// inside of `Fn` when parsed.
521
564
MapInput :: Fn ( _) => unimplemented ! ( ) ,
522
565
// For structs/unions/aliases, their type is the same as their identifier.
523
- MapInput :: Alias ( a) => ( a. ident ( ) , cdecl:: named ( a. ident ( ) , cdecl:: Constness :: Mut ) ) ,
524
- MapInput :: Struct ( s) => ( s. ident ( ) , cdecl:: named ( s. ident ( ) , cdecl:: Constness :: Mut ) ) ,
525
- MapInput :: Union ( u) => ( u. ident ( ) , cdecl:: named ( u. ident ( ) , cdecl:: Constness :: Mut ) ) ,
566
+ // FIXME(ctest): For some specific primitives such as c_uint, they don't exist on the
567
+ // C side and have to be manually translated. If they are removed to use `std::ffi`,
568
+ // then this becomes unneeded (although it won't break).
569
+ MapInput :: Alias ( a) => ( a. ident ( ) , cdecl:: named ( a. ident ( ) , Constness :: Mut ) ) ,
570
+ MapInput :: Struct ( s) => ( s. ident ( ) , cdecl:: named ( s. ident ( ) , Constness :: Mut ) ) ,
571
+ MapInput :: Union ( u) => ( u. ident ( ) , cdecl:: named ( u. ident ( ) , Constness :: Mut ) ) ,
526
572
527
573
MapInput :: StructType ( _) => panic ! ( "MapInput::StructType is not allowed!" ) ,
528
574
MapInput :: UnionType ( _) => panic ! ( "MapInput::UnionType is not allowed!" ) ,
@@ -539,7 +585,7 @@ impl<'a> TranslateHelper<'a> {
539
585
)
540
586
} ) ?;
541
587
542
- let item = if self . ffi_items . contains_struct ( ident ) {
588
+ let item = if self . ffi_items . contains_struct ( & ty ) {
543
589
MapInput :: StructType ( & ty)
544
590
} else if self . ffi_items . contains_union ( ident) {
545
591
MapInput :: UnionType ( & ty)
0 commit comments