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