1 #include <stdio.h>
2 #include <stdlib.h>
3
4
5 static int
randnum(int from,int to)6 randnum(int from, int to) {
7 static int init;
8 if (!init) {
9 srand((unsigned)time(NULL));
10 init = 1;
11 }
12
13 return from + (((double)rand() + 1) / RAND_MAX) * (to - from);
14 }
15
16 static const char *
get_rand_type(void)17 get_rand_type(void) {
18 static const char *types[] = {
19 "char", "short", "int", "float", "double", "long long", "void *"
20 };
21 return types[ randnum(0, sizeof types / sizeof *types) ];
22 }
23
24 int
main(void)25 main(void) {
26 int members;
27 int mixlimit;
28 int bits[128];
29 int i;
30
31 /* Set count of bitfield members */
32 members = randnum(1, 12);
33
34 /* Set upper bound for mixed types */
35 mixlimit = randnum(1, 7);
36
37 printf("#include <stdio.h>\n");
38 printf("#include <string.h>\n");
39 printf("static void dump(void *p, size_t count) {\n");
40 printf(" unsigned char *ucp = p;\n");
41 printf(" size_t i;\n");
42 printf(" for (i = 0; i < count; ++i) {\n");
43 printf(" printf(\"%%02x\", *ucp++);\n");
44 printf(" }\n");
45 printf(" putchar('\\n');\n");
46 printf(" }\n\n");
47
48 printf("int main(void) {\n");
49 printf(" struct foo {\n");
50 for (i = 0; i < members; ++i) {
51 int msize = randnum(1, 32);
52 char *type = randnum(0,1) == 0? "unsigned": "int"; /* _Bool? */
53
54 if (randnum(0,mixlimit) == 1) {
55 /* Insert "freak" type */
56 printf(" %s dummy%d;\n", get_rand_type(), i);
57 }
58
59 printf(" %s m%d:%d;\n", type, i, msize);
60 bits[i] = msize; /* Save size for later use */
61 }
62 printf(" } f;\n");
63
64 /*
65 * For all bitfield members: Check that setting the member does not
66 * affect other member values (they have to remain 0). This
67 * indirectly also checks for incorrect storage layout in cases
68 * where no overlap happens because the output will reveal the bit
69 * pattern
70 */
71 for (i = 0; i < members; ++i) {
72 unsigned valmask;
73 int j;
74
75 valmask = 0;
76 for (j = 0; j < bits[i]; ++j) {
77 valmask <<= 1;
78 valmask |= 1;
79 }
80
81 printf(" memset(&f, 0, sizeof f);\n");
82 printf(" f.m%d = 0x%x;\n", i, valmask);
83 printf(" dump(&f, sizeof f);\n");
84 printf(" printf(\"%%d\\n\", f.m%d);\n", i);
85
86 }
87
88 printf("}\n");
89 }
90
91