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