• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use quickcheck::{Arbitrary, Gen, StdGen};
2 use rand::thread_rng;
3 use std::fmt;
4 
5 /// BaseTypeC is used in generation of C headers to represent the C language's
6 /// primitive types as well as `void*`.
7 #[derive(Debug, Clone)]
8 pub struct BaseTypeC {
9     /// String representation of C type.
10     pub def: String,
11 }
12 
13 /// TypeQualifierC is used in generation of C headers to represent qualifiers
14 /// such as `const`.
15 #[derive(Debug, Clone)]
16 pub struct TypeQualifierC {
17     /// String representation of C type qualifier.
18     pub def: String,
19 }
20 
21 /// PointerLevelC is used in generation of C headers to represent number of
22 /// `*` for pointer types.
23 #[derive(Debug, Clone)]
24 pub struct PointerLevelC {
25     /// String representation of C declaration's pointer level.
26     pub def: String,
27 }
28 
29 /// ArrayDimensionC is used in generation of C headers to represent number of
30 /// `[]` used to define array types.
31 #[derive(Debug, Clone)]
32 pub struct ArrayDimensionC {
33     /// String representation of C declaration's array dimension.
34     pub def: String,
35 }
36 
37 /// BasicTypeDeclarationC is used in generation of C headers to represent
38 /// declarations outside of function pointers that take the form
39 /// `BaseTypeC` + `TypeQualifierC` + `PointerLevelC` + `ident_id`.
40 #[derive(Debug, Clone)]
41 pub struct BasicTypeDeclarationC {
42     /// The declaration's base type, i.e. `int`.
43     pub type_name: BaseTypeC,
44     /// The declaration's type qualifier, i.e. `const`.
45     pub type_qualifier: TypeQualifierC,
46     /// The declaration's pointer level, i.e. `***`.
47     pub pointer_level: PointerLevelC,
48     /// The declaration's array dimension, i.e. [][][].
49     pub array_dimension: ArrayDimensionC,
50     /// The declaration's identifier, i.e. ident_N.
51     pub ident_id: String,
52 }
53 
54 /// StructDeclarationC is used in generation of C headers to represent the
55 /// definition of a struct type.
56 #[derive(Debug, Clone)]
57 pub struct StructDeclarationC {
58     /// The declaration's fields.
59     pub fields: DeclarationListC,
60     /// The declaration's array dimension, i.e. [][][].
61     pub array_dimension: ArrayDimensionC,
62     /// The declaration's identifier, i.e. struct_N.
63     pub ident_id: String,
64 }
65 
66 /// UnionDeclarationC is used in generation of C headers to represent the
67 /// definition of a union type.
68 #[derive(Debug, Clone)]
69 pub struct UnionDeclarationC {
70     /// The declaration's fields.
71     pub fields: DeclarationListC,
72     /// The declaration's array dimension, i.e. [][][].
73     pub array_dimension: ArrayDimensionC,
74     /// The declaration's identifier, i.e. union_N.
75     pub ident_id: String,
76 }
77 
78 /// FunctionPointerDeclarationC is used in generation of C headers to represent
79 /// the definition of a function pointer type.
80 #[derive(Debug, Clone)]
81 pub struct FunctionPointerDeclarationC {
82     /// The function's type qualifier, i.e. `const`.
83     pub type_qualifier: TypeQualifierC,
84     /// The function's return type, i.e. `int`.
85     pub type_name: BaseTypeC,
86     /// The function's pointer level, i.e. `***`.
87     pub pointer_level: PointerLevelC,
88     /// The function's parameters.
89     pub params: ParameterListC,
90     /// The declaration's identifier, i.e. func_ptr_N.
91     pub ident_id: String,
92 }
93 
94 /// FunctionPrototypeC is used in generation of C headers to represent the
95 /// definition of a function prototype.
96 #[derive(Debug, Clone)]
97 pub struct FunctionPrototypeC {
98     /// The function's type qualifier, i.e. `const`.
99     pub type_qualifier: TypeQualifierC,
100     /// The function's return type, i.e. `int`.
101     pub type_name: BaseTypeC,
102     /// The function's pointer level, i.e. `***`.
103     pub pointer_level: PointerLevelC,
104     /// The function's parameters.
105     pub params: ParameterListC,
106     /// The prototype's identifier, i.e. `func_N`.
107     pub ident_id: String,
108 }
109 
110 /// ParameterC is used in generation of C headers to represent the
111 /// definition function parameters.
112 #[derive(Debug, Clone)]
113 pub struct ParameterC {
114     /// The parameter's type qualifier, i.e. `const`.
115     pub type_qualifier: TypeQualifierC,
116     /// The parameter's base type, i.e. `int`.
117     pub type_name: BaseTypeC,
118     /// The parameter's pointer level, i.e. `***`.
119     pub pointer_level: PointerLevelC,
120 }
121 
122 /// ParameterListC is used in generation of C headers to represent a list of
123 /// definitions of function parameters.
124 #[derive(Debug, Clone)]
125 pub struct ParameterListC {
126     /// Parameters that define a C function signature.
127     pub params: Vec<ParameterC>,
128 }
129 
130 /// DeclarationC is used in generation of C headers to represent all supported
131 /// C type declarations allowed in the generated header.
132 #[derive(Debug, Clone)]
133 pub enum DeclarationC {
134     /// Function prototype declaration kind.
135     FunctionDecl(FunctionPrototypeC),
136     /// Function pointer declaration kind.
137     FunctionPtrDecl(FunctionPointerDeclarationC),
138     /// Struct declaration kind.
139     StructDecl(StructDeclarationC),
140     /// Union declaration kind.
141     UnionDecl(UnionDeclarationC),
142     /// Basic type declaration kind.
143     VariableDecl(BasicTypeDeclarationC),
144 }
145 
146 /// DeclarationListC is used in generation of C headers to represent a list of
147 /// declarations.
148 #[derive(Debug, Clone)]
149 pub struct DeclarationListC {
150     /// Grouping of C declarations.
151     pub decls: Vec<DeclarationC>,
152 }
153 
154 /// HeaderC is used in generation of C headers to represent a collection of
155 /// declarations.
156 #[derive(Clone)]
157 pub struct HeaderC {
158     /// The header's declarations.
159     pub def: DeclarationListC,
160 }
161 
162 /// MakeUnique is used in generation of C headers to make declaration
163 /// identifiers unique by incorporating the `stamp` parameter into it's name.
164 trait MakeUnique {
make_unique(&mut self, stamp: usize)165     fn make_unique(&mut self, stamp: usize);
166 }
167 
168 /// MakeUnique is used in generation of C headers to make DeclarationC
169 /// identifiers unique.
170 impl MakeUnique for DeclarationC {
make_unique(&mut self, stamp: usize)171     fn make_unique(&mut self, stamp: usize) {
172         match *self {
173             DeclarationC::FunctionDecl(ref mut d) => d.make_unique(stamp),
174             DeclarationC::FunctionPtrDecl(ref mut d) => d.make_unique(stamp),
175             DeclarationC::StructDecl(ref mut d) => d.make_unique(stamp),
176             DeclarationC::UnionDecl(ref mut d) => d.make_unique(stamp),
177             DeclarationC::VariableDecl(ref mut d) => d.make_unique(stamp),
178         }
179     }
180 }
181 
182 /// A qucickcheck trait for describing how DeclarationC types can be
183 /// randomly generated and shrunk.
184 impl Arbitrary for DeclarationC {
arbitrary<G: Gen>(g: &mut G) -> DeclarationC185     fn arbitrary<G: Gen>(g: &mut G) -> DeclarationC {
186         match g.gen_range(0, 5) {
187             0 => DeclarationC::FunctionDecl(FunctionPrototypeC::arbitrary(g)),
188             1 => DeclarationC::FunctionPtrDecl(
189                 FunctionPointerDeclarationC::arbitrary(g),
190             ),
191             2 => DeclarationC::StructDecl(StructDeclarationC::arbitrary(g)),
192             3 => DeclarationC::UnionDecl(UnionDeclarationC::arbitrary(g)),
193             4 => {
194                 DeclarationC::VariableDecl(BasicTypeDeclarationC::arbitrary(g))
195             }
196             _ => unreachable!(),
197         }
198     }
199 }
200 
201 /// Enables to string and format for DeclarationC types.
202 impl fmt::Display for DeclarationC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result203     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204         match *self {
205             DeclarationC::FunctionPtrDecl(ref d) => write!(f, "{}", d),
206             DeclarationC::StructDecl(ref d) => write!(f, "{}", d),
207             DeclarationC::UnionDecl(ref d) => write!(f, "{}", d),
208             DeclarationC::VariableDecl(ref d) => write!(f, "{}", d),
209             DeclarationC::FunctionDecl(ref d) => write!(f, "{}", d),
210         }
211     }
212 }
213 
214 /// A qucickcheck trait for describing how DeclarationListC types can be
215 /// randomly generated and shrunk.
216 impl Arbitrary for DeclarationListC {
arbitrary<G: Gen>(g: &mut G) -> DeclarationListC217     fn arbitrary<G: Gen>(g: &mut G) -> DeclarationListC {
218         DeclarationListC {
219             decls: Arbitrary::arbitrary(g),
220         }
221     }
222 }
223 
224 /// Enables to string and format for DeclarationListC types.
225 impl fmt::Display for DeclarationListC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result226     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227         let mut display = String::new();
228         for decl in &self.decls {
229             display += &format!("{}", decl);
230         }
231         write!(f, "{}", display)
232     }
233 }
234 
235 /// A qucickcheck trait for describing how BaseTypeC types can be
236 /// randomly generated and shrunk.
237 impl Arbitrary for BaseTypeC {
arbitrary<G: Gen>(g: &mut G) -> BaseTypeC238     fn arbitrary<G: Gen>(g: &mut G) -> BaseTypeC {
239         // Special case `long double` until issue #550 is resolved.
240         let base_type = vec![
241             "char",
242             "signed char",
243             "unsigned char",
244             "short",
245             "short int",
246             "signed short",
247             "signed short int",
248             "unsigned short",
249             "unsigned short int",
250             "int",
251             "signed",
252             "signed int",
253             "unsigned",
254             "unsigned int",
255             "long",
256             "long int",
257             "signed long",
258             "signed long int",
259             "unsigned long",
260             "unsigned long int",
261             "long long",
262             "long long int",
263             "signed long long",
264             "signed long long int",
265             "unsigned long long",
266             "unsigned long long int",
267             "float",
268             "double",
269             #[cfg(feature = "long-doubles")]
270             "long double",
271             "void*",
272         ];
273         BaseTypeC {
274             def: String::from(*g.choose(&base_type).unwrap()),
275         }
276     }
277 }
278 
279 /// Enables to string and format for BaseTypeC types,
280 impl fmt::Display for BaseTypeC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result281     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282         write!(f, "{}", self.def)
283     }
284 }
285 
286 /// A qucickcheck trait for describing how TypeQualifierC types can be
287 /// randomly generated and shrunk.
288 impl Arbitrary for TypeQualifierC {
arbitrary<G: Gen>(g: &mut G) -> TypeQualifierC289     fn arbitrary<G: Gen>(g: &mut G) -> TypeQualifierC {
290         let qualifier = vec!["const", ""];
291         TypeQualifierC {
292             def: String::from(*g.choose(&qualifier).unwrap()),
293         }
294     }
295 }
296 
297 /// Enables to string and format for TypeQualifierC types.
298 impl fmt::Display for TypeQualifierC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result299     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300         write!(f, "{}", self.def)
301     }
302 }
303 
304 /// A qucickcheck trait for describing how PointerLevelC types can be
305 /// randomly generated and shrunk.
306 impl Arbitrary for PointerLevelC {
arbitrary<G: Gen>(g: &mut G) -> PointerLevelC307     fn arbitrary<G: Gen>(g: &mut G) -> PointerLevelC {
308         PointerLevelC {
309             // 16 is an arbitrary "not too big" number for capping pointer level.
310             def: (0..g.gen_range(0, 16)).map(|_| "*").collect::<String>(),
311         }
312     }
313 }
314 
315 /// Enables to string and format for PointerLevelC types.
316 impl fmt::Display for PointerLevelC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result317     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318         write!(f, "{}", self.def)
319     }
320 }
321 
322 /// A qucickcheck trait for describing how ArrayDimensionC types can be
323 /// randomly generated and shrunk.
324 impl Arbitrary for ArrayDimensionC {
arbitrary<G: Gen>(g: &mut G) -> ArrayDimensionC325     fn arbitrary<G: Gen>(g: &mut G) -> ArrayDimensionC {
326         // Keep these small, clang complains when they get too big.
327         let dimensions = g.gen_range(0, 5);
328         let mut def = String::new();
329 
330         let lower_bound = i32::from(cfg!(feature = "zero-sized-arrays"));
331 
332         for _ in 1..dimensions {
333             // 16 is an arbitrary "not too big" number for capping array size.
334             def += &format!("[{}]", g.gen_range(lower_bound, 16));
335         }
336         ArrayDimensionC { def }
337     }
338 }
339 
340 /// Enables to string and format for ArrayDimensionC types.
341 impl fmt::Display for ArrayDimensionC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result342     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343         write!(f, "{}", self.def)
344     }
345 }
346 
347 /// MakeUnique is used in generation of C headers to make BasicTypeDeclarationC
348 /// identifiers unique.
349 impl MakeUnique for BasicTypeDeclarationC {
make_unique(&mut self, stamp: usize)350     fn make_unique(&mut self, stamp: usize) {
351         self.ident_id += &format!("_{}", stamp);
352     }
353 }
354 
355 /// A qucickcheck trait for describing how BasicTypeDeclarationC types can be
356 /// randomly generated and shrunk.
357 impl Arbitrary for BasicTypeDeclarationC {
arbitrary<G: Gen>(g: &mut G) -> BasicTypeDeclarationC358     fn arbitrary<G: Gen>(g: &mut G) -> BasicTypeDeclarationC {
359         BasicTypeDeclarationC {
360             type_qualifier: Arbitrary::arbitrary(g),
361             type_name: Arbitrary::arbitrary(g),
362             pointer_level: Arbitrary::arbitrary(g),
363             array_dimension: Arbitrary::arbitrary(g),
364             ident_id: format!("{}", usize::arbitrary(g)),
365         }
366     }
367 }
368 
369 /// Enables to string and format for BasicTypeDeclarationC types.
370 impl fmt::Display for BasicTypeDeclarationC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result371     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372         write!(
373             f,
374             "{} {} {} ident_{}{};",
375             self.type_qualifier,
376             self.type_name,
377             self.pointer_level,
378             self.ident_id,
379             self.array_dimension
380         )
381     }
382 }
383 
384 /// MakeUnique is used in generation of C headers to make StructDeclarationC
385 /// identifiers unique.
386 impl MakeUnique for StructDeclarationC {
make_unique(&mut self, stamp: usize)387     fn make_unique(&mut self, stamp: usize) {
388         self.ident_id += &format!("_{}", stamp);
389     }
390 }
391 
392 /// A qucickcheck trait for describing how StructDeclarationC types can be
393 /// randomly generated and shrunk.
394 impl Arbitrary for StructDeclarationC {
arbitrary<G: Gen>(g: &mut G) -> StructDeclarationC395     fn arbitrary<G: Gen>(g: &mut G) -> StructDeclarationC {
396         // Reduce generator size as a method of putting a bound on recursion.
397         // When size < 1 the empty list is generated.
398         let reduced_size: usize = (g.size() / 2) + 1;
399         let mut decl_list: DeclarationListC =
400             Arbitrary::arbitrary(&mut StdGen::new(thread_rng(), reduced_size));
401         let mut fields: DeclarationListC = DeclarationListC { decls: vec![] };
402 
403         for (i, decl) in decl_list.decls.iter_mut().enumerate() {
404             match *decl {
405                 DeclarationC::FunctionDecl(_) => {}
406                 ref mut decl => {
407                     decl.make_unique(i);
408                     fields.decls.push(decl.clone());
409                 }
410             }
411         }
412 
413         StructDeclarationC {
414             fields,
415             ident_id: format!("{}", usize::arbitrary(g)),
416             array_dimension: Arbitrary::arbitrary(g),
417         }
418     }
419 }
420 
421 /// Enables to string and format for StructDeclarationC types.
422 impl fmt::Display for StructDeclarationC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result423     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424         write!(
425             f,
426             "struct {{ {} }} struct_{}{};",
427             self.fields, self.ident_id, self.array_dimension
428         )
429     }
430 }
431 
432 /// MakeUnique is used in generation of C headers to make UnionDeclarationC
433 /// identifiers unique.
434 impl MakeUnique for UnionDeclarationC {
make_unique(&mut self, stamp: usize)435     fn make_unique(&mut self, stamp: usize) {
436         self.ident_id += &format!("_{}", stamp);
437     }
438 }
439 
440 /// A qucickcheck trait for describing how UnionDeclarationC types can be
441 /// randomly generated and shrunk.
442 impl Arbitrary for UnionDeclarationC {
arbitrary<G: Gen>(g: &mut G) -> UnionDeclarationC443     fn arbitrary<G: Gen>(g: &mut G) -> UnionDeclarationC {
444         // Reduce generator size as a method of putting a bound on recursion.
445         // When size < 1 the empty list is generated.
446         let reduced_size: usize = (g.size() / 2) + 1;
447         let mut decl_list: DeclarationListC =
448             Arbitrary::arbitrary(&mut StdGen::new(thread_rng(), reduced_size));
449         let mut fields: DeclarationListC = DeclarationListC { decls: vec![] };
450 
451         for (i, decl) in decl_list.decls.iter_mut().enumerate() {
452             match *decl {
453                 DeclarationC::FunctionDecl(_) => {}
454                 ref mut decl => {
455                     decl.make_unique(i);
456                     fields.decls.push(decl.clone());
457                 }
458             }
459         }
460 
461         UnionDeclarationC {
462             fields,
463             ident_id: format!("{}", usize::arbitrary(g)),
464             array_dimension: Arbitrary::arbitrary(g),
465         }
466     }
467 }
468 
469 /// Enables to string and format for UnionDeclarationC types.
470 impl fmt::Display for UnionDeclarationC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result471     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
472         write!(
473             f,
474             "union {{ {} }} union_{}{};",
475             self.fields, self.ident_id, self.array_dimension
476         )
477     }
478 }
479 
480 /// MakeUnique is used in generation of C headers to make
481 /// FunctionPointerDeclarationC identifiers unique.
482 impl MakeUnique for FunctionPointerDeclarationC {
make_unique(&mut self, stamp: usize)483     fn make_unique(&mut self, stamp: usize) {
484         self.ident_id += &format!("_{}", stamp);
485     }
486 }
487 
488 /// A qucickcheck trait for describing how FunctionPointerDeclarationC types can
489 /// be randomly generated and shrunk.
490 impl Arbitrary for FunctionPointerDeclarationC {
arbitrary<G: Gen>(g: &mut G) -> FunctionPointerDeclarationC491     fn arbitrary<G: Gen>(g: &mut G) -> FunctionPointerDeclarationC {
492         FunctionPointerDeclarationC {
493             type_qualifier: Arbitrary::arbitrary(g),
494             type_name: Arbitrary::arbitrary(g),
495             pointer_level: Arbitrary::arbitrary(g),
496             params: Arbitrary::arbitrary(g),
497             ident_id: format!("{}", usize::arbitrary(g)),
498         }
499     }
500 }
501 
502 /// Enables to string and format for FunctionPointerDeclarationC types.
503 impl fmt::Display for FunctionPointerDeclarationC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result504     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
505         write!(
506             f,
507             "{} {} {} (*func_ptr_{})({});",
508             self.type_qualifier,
509             self.type_name,
510             self.pointer_level,
511             self.ident_id,
512             self.params
513         )
514     }
515 }
516 
517 /// MakeUnique is used in generation of C headers to make FunctionPrototypeC
518 /// identifiers unique.
519 impl MakeUnique for FunctionPrototypeC {
make_unique(&mut self, stamp: usize)520     fn make_unique(&mut self, stamp: usize) {
521         self.ident_id += &format!("_{}", stamp);
522     }
523 }
524 
525 /// A qucickcheck trait for describing how FunctionPrototypeC types can be
526 /// randomly generated and shrunk.
527 impl Arbitrary for FunctionPrototypeC {
arbitrary<G: Gen>(g: &mut G) -> FunctionPrototypeC528     fn arbitrary<G: Gen>(g: &mut G) -> FunctionPrototypeC {
529         FunctionPrototypeC {
530             type_qualifier: Arbitrary::arbitrary(g),
531             type_name: Arbitrary::arbitrary(g),
532             pointer_level: Arbitrary::arbitrary(g),
533             params: Arbitrary::arbitrary(g),
534             ident_id: format!("{}", usize::arbitrary(g)),
535         }
536     }
537 }
538 
539 /// Enables to string and format for FunctionPrototypeC types.
540 impl fmt::Display for FunctionPrototypeC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result541     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542         write!(
543             f,
544             "{} {} {} func_{}({});",
545             self.type_qualifier,
546             self.type_name,
547             self.pointer_level,
548             self.ident_id,
549             self.params
550         )
551     }
552 }
553 
554 /// A qucickcheck trait for describing how ParameterC types can be
555 /// randomly generated and shrunk.
556 impl Arbitrary for ParameterC {
arbitrary<G: Gen>(g: &mut G) -> ParameterC557     fn arbitrary<G: Gen>(g: &mut G) -> ParameterC {
558         ParameterC {
559             type_qualifier: Arbitrary::arbitrary(g),
560             type_name: Arbitrary::arbitrary(g),
561             pointer_level: Arbitrary::arbitrary(g),
562         }
563     }
564 }
565 
566 /// Enables to string and format for ParameterC types.
567 impl fmt::Display for ParameterC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result568     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
569         write!(
570             f,
571             "{} {} {}",
572             self.type_qualifier, self.type_name, self.pointer_level
573         )
574     }
575 }
576 
577 /// A qucickcheck trait for describing how ParameterListC types can be
578 /// randomly generated and shrunk.
579 impl Arbitrary for ParameterListC {
arbitrary<G: Gen>(g: &mut G) -> ParameterListC580     fn arbitrary<G: Gen>(g: &mut G) -> ParameterListC {
581         ParameterListC {
582             params: Arbitrary::arbitrary(g),
583         }
584     }
585 }
586 
587 /// Enables to string and format for ParameterListC types.
588 impl fmt::Display for ParameterListC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result589     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
590         let mut display = String::new();
591         for (i, p) in self.params.iter().enumerate() {
592             match i {
593                 0 => display += &format!("{}", p),
594                 _ => display += &format!(",{}", p),
595             }
596         }
597         write!(f, "{}", display)
598     }
599 }
600 
601 /// A qucickcheck trait for describing how HeaderC types can be
602 /// randomly generated and shrunk.
603 impl Arbitrary for HeaderC {
arbitrary<G: Gen>(g: &mut G) -> HeaderC604     fn arbitrary<G: Gen>(g: &mut G) -> HeaderC {
605         let mut decl_list: DeclarationListC = Arbitrary::arbitrary(g);
606         for (i, decl) in decl_list.decls.iter_mut().enumerate() {
607             decl.make_unique(i);
608         }
609         HeaderC { def: decl_list }
610     }
611 }
612 
613 /// Enables to string and format for HeaderC types.
614 impl fmt::Display for HeaderC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result615     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616         let mut display = String::new();
617         for decl in &self.def.decls {
618             display += &format!("{}", decl);
619         }
620         write!(f, "{}", display)
621     }
622 }
623 
624 /// Use Display trait for Debug so that any failing property tests report
625 /// generated C code rather than the data structures that contain it.
626 impl fmt::Debug for HeaderC {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result627     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
628         write!(f, "{}", self)
629     }
630 }
631