📄 struct-layout-1_generate.c
字号:
if (ea[i].attrib && strcmp (ea[i].attrib, eb[i].attrib) != 0) return 0; } return 1;}static int e_exists (const struct entry *e) { struct entry *h; hashval_t hval; hval = e_hash (e); for (h = hash_table[hval % HASH_SIZE]; h; h = h->next) if (e_eq (e, h)) return 1; return 0;}static voide_insert (struct entry *e){ hashval_t hval; hval = e_hash (e); e->next = hash_table[hval % HASH_SIZE]; hash_table[hval % HASH_SIZE] = e;}voidoutput (struct entry *e){ int i; char c; struct entry *n; if (e[0].etype != ETYPE_STRUCT && e[0].etype != ETYPE_UNION) abort (); if (e_exists (e)) return; n = (struct entry *) malloc ((e[0].len + 1) * sizeof (struct entry)); memcpy (n, e, (e[0].len + 1) * sizeof (struct entry)); e_insert (n); if (idx == limidx) switchfiles (e[0].len); if (e[0].etype == ETYPE_STRUCT) fprintf (outfile, "T(%d,", idx); else fprintf (outfile, "U(%d,", idx); c = 'a'; for (i = 1; i <= e[0].len; ) i += subfield (e + i, &c); fputs (",", outfile); c = 'a'; for (i = 1; i <= e[0].len; ) { i += subvalues (e + i, namebuf, &c); if (e[0].etype == ETYPE_UNION) break; } fputs (")\n", outfile); if (output_one && idx == limidx) exit (0); ++idx;}enum FEATURE{ FEATURE_VECTOR = 1, FEATURE_ALIGNEDPACKED = 2, FEATURE_ZEROARRAY = 4, FEATURE_ZEROBITFLD = 8, ALL_FEATURES = FEATURE_VECTOR | FEATURE_ZEROARRAY | FEATURE_ALIGNEDPACKED | FEATURE_ZEROBITFLD};voidsingles (enum FEATURE features){ struct entry e[2]; int i; memset (e, 0, sizeof (e)); e[0].etype = ETYPE_STRUCT; output (e); e[0].etype = ETYPE_UNION; output (e); e[0].len = 1; for (i = 0; i < NTYPES2; ++i) { e[0].etype = ETYPE_STRUCT; e[1].etype = ETYPE_TYPE; e[1].type = &base_types[i]; output (e); e[0].etype = ETYPE_UNION; output (e); } if (features & FEATURE_VECTOR) for (i = 0; i < NVTYPES2; ++i) { e[0].etype = ETYPE_STRUCT; e[1].etype = ETYPE_TYPE; e[1].type = &vector_types[i]; output (e); e[0].etype = ETYPE_UNION; output (e); }}voidchoose_type (enum FEATURE features, struct entry *e, int r, int in_array){ int i; i = NTYPES2 - NTYPES1; if (features & FEATURE_VECTOR) i += NVTYPES2; if ((r & 3) == 0) { if (in_array) i += NAATYPES2; else i += NATYPES2; } r >>= 2; r %= i; if (r < NTYPES2 - NTYPES1) e->type = &base_types[r + NTYPES1]; r -= NTYPES2 - NTYPES1; if (e->type == NULL && (features & FEATURE_VECTOR)) { if (r < NVTYPES2) e->type = &vector_types[r]; r -= NVTYPES2; } if (e->type == NULL && !in_array) { if (r < NATYPES2) e->type = &attrib_types[r]; r -= NATYPES2; } if (e->type == NULL && in_array) { if (r < NAATYPES2) e->type = &attrib_array_types[r]; r -= NAATYPES2; } if (e->type == NULL) abort ();}/* This is from gcc.c-torture/execute/builtin-bitops-1.c. */static intmy_ffsll (unsigned long long x){ int i; if (x == 0) return 0; /* We've tested LLONG_MAX for 64 bits so this should be safe. */ for (i = 0; i < 64; i++) if (x & (1ULL << i)) break; return i + 1;}voidgenerate_fields (enum FEATURE features, struct entry *e, struct entry *parent, int len){ int r, i, j, ret = 1, n, incr, sametype; for (n = 0; n < len; n += incr) { r = generate_random (); /* 50% ETYPE_TYPE base_types NTYPES1 12.5% ETYPE_TYPE other 12.5% ETYPE_ARRAY 12.5% ETYPE_BITFLD 12.5% ETYPE_STRUCT|ETYPE_UNION|ETYPE_STRUCT_ARRAY|ETYPE_UNION_ARRAY */ i = (r & 7); r >>= 3; incr = 1; switch (i) { case 0: case 1: case 2: case 3: e[n].etype = ETYPE_TYPE; e[n].type = &base_types[r % NTYPES1]; break; case 4: e[n].etype = ETYPE_TYPE; choose_type (features, &e[n], r, 0); break; case 5: e[n].etype = ETYPE_ARRAY; i = r & 1; r >>= 1; if (i) e[n].type = &base_types[r % NTYPES1]; else choose_type (features, &e[n], r, 1); r = generate_random (); if ((features & FEATURE_ZEROARRAY) && (r & 3) == 0) { e[n].arr_len = 0; if (n == len - 1 && (r & 4) && (parent->etype == ETYPE_STRUCT || parent->etype == ETYPE_STRUCT_ARRAY)) { int k; for (k = 0; k < n; ++k) if (e[k].etype != ETYPE_BITFLD || e[k].len) { e[n].arr_len = 255; break; } } } else if ((r & 3) != 3) e[n].arr_len = (r >> 2) & 7; else e[n].arr_len = (r >> 2) & 31; break; case 6: sametype = 1; switch (r & 7) { case 0: case 1: case 2: break; case 3: case 4: case 5: incr = 1 + (r >> 3) % (len - n); break; case 6: case 7: sametype = 0; incr = 1 + (r >> 3) % (len - n); break; } for (j = n; j < n + incr; ++j) { int mi, ma; e[j].etype = ETYPE_BITFLD; if (j == n || !sametype) { int k; r = generate_random (); k = r & 3; r >>= 2; if (!k) e[j].type = &aligned_bitfld_types[r % n_aligned_bitfld_types]; else e[j].type = &bitfld_types[r % n_bitfld_types]; } else e[j].type = e[n].type; r = generate_random (); mi = 0; ma = 0; switch (e[j].type->bitfld) { case 'C': ma = 8; break; case 'S': ma = 16; break; case 'I': ma = 32; break; case 'L': case 'Q': ma = 64; break; case 'B': ma = 1; break; case ' ': if (e[j].type->type == TYPE_UENUM) mi = my_ffsll (e[j].type->maxval + 1) - 1; else if (e[j].type->type == TYPE_SENUM) mi = my_ffsll (e[j].type->maxval + 1); else abort (); if (!mi) mi = 1; if (mi > 32) ma = 64; else if (mi > 16 || !short_enums) ma = 32; else if (mi > 8) ma = 16; else ma = 8; break; default: abort (); } e[j].len = ma + 1; if (sametype && (r & 3) == 0 && ma > 1) { int sum = 0, k; for (k = n; k < j; ++k) sum += e[k].len; sum %= ma; e[j].len = sum ? ma - sum : ma; } r >>= 2; if (!sametype && (r & 7) == 0) ma *= 8; r >>= 3; if (! (features & FEATURE_ZEROBITFLD) && mi == 0) mi = 1; if (e[j].len < mi || e[j].len > ma) e[j].len = mi + (r % (ma + 1 - mi)); r >>= 6; if ((features & FEATURE_ZEROBITFLD) && (r & 3) == 0 && mi == 0) e[j].len = 0; } break; case 7: switch (r & 7) { case 0: case 1: case 2: e[n].etype = ETYPE_STRUCT; break; case 3: case 4: e[n].etype = ETYPE_UNION; break; case 5: case 6: e[n].etype = ETYPE_STRUCT_ARRAY; break; case 7: e[n].etype = ETYPE_UNION_ARRAY; break; } r >>= 3; e[n].len = r % (len - n); incr = 1 + e[n].len; generate_fields (features, &e[n + 1], &e[n], e[n].len); if (e[n].etype == ETYPE_STRUCT_ARRAY || e[n].etype == ETYPE_UNION_ARRAY) { r = generate_random (); if ((features & FEATURE_ZEROARRAY) && (r & 3) == 0) { e[n].arr_len = 0; if (n + incr == len && (r & 4) && (parent->etype == ETYPE_STRUCT || parent->etype == ETYPE_STRUCT_ARRAY)) { int k; for (k = 0; k < n; ++k) if (e[k].etype != ETYPE_BITFLD || e[k].len) { e[n].arr_len = 255; break; } } } else if ((r & 3) != 3) e[n].arr_len = (r >> 2) & 7; else e[n].arr_len = (r >> 2) & 31; } break; } r = generate_random (); if ((r & 7) == 0) { r >>= 3; i = (features & FEATURE_ALIGNEDPACKED) ? NATTRIBS2 : NATTRIBS1; e[n].attrib = attributes[r % i]; if (! (features & FEATURE_ALIGNEDPACKED) && strcmp (e[n].attrib, "atpa") == 0 && ((e[n].type >= &attrib_types[0] && e[n].type < &attrib_types[NATYPES2]) || (e[n].type >= &attrib_array_types[0] && e[n].type < &attrib_array_types[NAATYPES2]) || (e[n].type >= &aligned_bitfld_types[0] && e[n].type < &aligned_bitfld_types[n_aligned_bitfld_types]))) e[n].attrib = NULL; } }}voidgenerate_random_tests (enum FEATURE features, int len){ struct entry e[len + 1]; int i, r; if (len > 'z' - 'a' + 1) abort (); memset (e, 0, sizeof (e)); r = generate_random (); if ((r & 7) == 0) e[0].etype = ETYPE_UNION; else e[0].etype = ETYPE_STRUCT; r >>= 3; e[0].len = len; generate_fields (features, &e[1], &e[0], len); output (e);}struct { const char *name; enum FEATURE f; }features[] = {{ "normal", 0 },{ "vector", FEATURE_VECTOR },{ "[0] :0", FEATURE_ZEROARRAY | FEATURE_ZEROBITFLD },{ "vector [0]", FEATURE_VECTOR | FEATURE_ZEROARRAY },{ "aligned packed vector [0] :0", FEATURE_VECTOR | FEATURE_ZEROARRAY | FEATURE_ALIGNEDPACKED | FEATURE_ZEROBITFLD },};intmain (int argc, char **argv){ int i, j, count, c, n = 3000; char *optarg; if (sizeof (int) != 4 || sizeof (long long) != 8) return 1; i = 1; while (i < argc) { c = '\0'; if (argv[i][0] == '-' && argv[i][2] == '\0') c = argv[i][1]; optarg = argv[i + 1]; if (!optarg) goto usage; switch (c) { case 'n': n = atoi (optarg); break; case 'd': destdir = optarg; break; case 's': srcdir = optarg; break; case 'i': output_one = 1; limidx = atoi (optarg); break; case 'e': short_enums = 1; i--; break; default: fprintf (stderr, "unrecognized option %s\n", argv[i]); goto usage; } i += 2; } if (output_one) { outfile = fopen ("/dev/null", "w"); if (outfile == NULL) { fputs ("could not open /dev/null", stderr); return 1; } n = limidx + 1; } if (destdir == NULL && !output_one) { usage: fprintf (stderr, "Usage:\n\%s [-e] [-s srcdir -d destdir] [-n count] [-i idx]\n\Either -s srcdir -d destdir or -i idx must be used\n", argv[0]); return 1; } if (srcdir == NULL && !output_one) goto usage; for (i = 0; i < NTYPES2; ++i) if (base_types[i].bitfld) bitfld_types[n_bitfld_types++] = base_types[i]; for (i = 0; i < NATYPES2; ++i) if (attrib_types[i].bitfld) aligned_bitfld_types[n_aligned_bitfld_types++] = attrib_types[i]; for (i = 0; i < sizeof (features) / sizeof (features[0]); ++i) { int startidx = idx; if (! output_one) limidx = idx; if (!i) count = 200; else count = 20; for (j = 1; j <= 9; ++j) while (idx < startidx + j * count) generate_random_tests (features[i].f, j); while (idx < startidx + count * 10) generate_random_tests (features[i].f, 10 + (generate_random () % 16)); } for (i = 0; n > 3000 && i < sizeof (features) / sizeof (features[0]); ++i) { int startidx; startidx = idx; if (! output_one) limidx = idx; singles (features[i].f); if (!i) { count = 1000; while (idx < startidx + 1000) generate_random_tests (features[i].f, 1); } else { startidx = idx; count = 100; while (idx < startidx + 100) generate_random_tests (features[i].f, 1); } startidx = idx; for (j = 2; j <= 9; ++j) while (idx < startidx + (j - 1) * count) generate_random_tests (features[i].f, j); while (idx < startidx + count * 9) generate_random_tests (features[i].f, 10 + (generate_random () % 16)); } if (! output_one) limidx = idx; while (idx < n) generate_random_tests (ALL_FEATURES, 1 + (generate_random () % 25)); fclose (outfile); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -