1 /* Structure layout test generator.
2    Copyright (C) 2004, 2005, 2007, 2010, 2011 Free Software Foundation, Inc.
3    Contributed by Jakub Jelinek <jakub@redhat.com>.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 /* Compile with gcc -o struct-layout-1_generate{,.c} generate_random{,_r}.c */
22 
23 /* N.B. -- This program cannot use libiberty as that will not work
24    when testing an installed compiler.  */
25 #include <limits.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stddef.h>
30 /* We use our own pseudo-random number generator, so that it gives the same
31    values on all hosts.  */
32 #include "generate-random.h"
33 
34 #if LLONG_MAX != 9223372036854775807LL && __LONG_LONG_MAX__ != 9223372036854775807LL
35 # error Need 64-bit long long
36 #endif
37 
38 typedef unsigned int hashval_t;
39 
40 enum TYPE
41 {
42   TYPE_INT,
43   TYPE_UINT,
44   TYPE_CINT,
45   TYPE_CUINT,
46   TYPE_FLOAT,
47   TYPE_CFLOAT,
48   TYPE_SENUM,
49   TYPE_UENUM,
50   TYPE_PTR,
51   TYPE_FNPTR,
52   TYPE_OTHER
53 };
54 
55 struct types
56 {
57   const char *name;
58   enum TYPE type;
59   unsigned long long int maxval;
60   char bitfld;
61 };
62 
63 struct types base_types[] = {
64 /* As we don't know whether char will be signed or not, just limit ourselves
65    to unsigned values less than maximum signed char value.  */
66 { "char", TYPE_UINT, 127, 'C' },
67 { "signed char", TYPE_INT, 127, 'C' },
68 { "unsigned char", TYPE_UINT, 255, 'C' },
69 { "short int", TYPE_INT, 32767, 'S' },
70 { "unsigned short int", TYPE_UINT, 65535, 'S' },
71 { "int", TYPE_INT, 2147483647, 'I' },
72 { "unsigned int", TYPE_UINT, 4294967295U, 'I' },
73 { "long int", TYPE_INT, 9223372036854775807LL, 'L' },
74 { "unsigned long int", TYPE_UINT, 18446744073709551615ULL, 'L' },
75 { "long long int", TYPE_INT, 9223372036854775807LL, 'Q' },
76 { "unsigned long long int", TYPE_UINT, 18446744073709551615ULL, 'Q' },
77 { "bool", TYPE_UINT, 1, 'B' },
78 { "void *", TYPE_PTR, 0, 0 },
79 { "char *", TYPE_PTR, 0, 0 },
80 { "int *", TYPE_PTR, 0, 0 },
81 { "float", TYPE_FLOAT, 0, 0 },
82 { "double", TYPE_FLOAT, 0, 0 },
83 /*{ "long double", TYPE_FLOAT, 0, 0 },*/
84 /* Disabled as double and long double
85    are encoded thee same, currently  */
86 #define NTYPES1 16
87 #if 0
88 /* enums are disabled for now as it seems like their encoding is broken, we should
89    just encode them using their underlaying type but we don't.   */
90 { "enum E0", TYPE_UENUM, 0, ' ' },
91 { "enum E1", TYPE_UENUM, 1, ' ' },
92 { "enum E2", TYPE_SENUM, 3, ' ' },
93 { "enum E3", TYPE_SENUM, 127, ' ' },
94 { "enum E4", TYPE_UENUM, 255, ' ' },
95 { "enum E5", TYPE_SENUM, 32767, ' ' },
96 { "enum E6", TYPE_UENUM, 65535, ' ' },
97 { "enum E7", TYPE_SENUM, 2147483647, ' ' },
98 { "enum E8", TYPE_UENUM, 4294967295U, ' ' },
99 { "enum E9", TYPE_SENUM, 1099511627775LL, ' ' },
100 #endif
101 #define NTYPES2 (sizeof (base_types) / sizeof (base_types[0]))
102 };
103 struct types complex_types[] = {
104 { "_Complex char", TYPE_CUINT, 127, 0 },
105 { "_Complex signed char", TYPE_CINT, 127, 0 },
106 { "_Complex unsigned char", TYPE_CUINT, 255, 0 },
107 { "_Complex short int", TYPE_CINT, 32767, 0 },
108 { "_Complex unsigned short int", TYPE_CUINT, 65535, 0 },
109 { "_Complex int", TYPE_CINT, 2147483647, 0 },
110 { "_Complex unsigned int", TYPE_CUINT, 4294967295U, 0 },
111 { "_Complex long int", TYPE_CINT, 9223372036854775807LL, 0 },
112 { "_Complex unsigned long int", TYPE_CUINT, 18446744073709551615ULL, 0 },
113 { "_Complex long long int", TYPE_CINT, 9223372036854775807LL, 0 },
114 { "_Complex unsigned long long int", TYPE_CUINT, 18446744073709551615ULL, 0 },
115 { "_Complex float", TYPE_CFLOAT, 0, 0 },
116 { "_Complex double", TYPE_CFLOAT, 0, 0 },
117 /*{ "_Complex long double", TYPE_CFLOAT, 0, 0 }, */
118 /* Disable until long doubles are encoded correctly.   */
119 #define NCTYPES2 (sizeof (complex_types) / sizeof (complex_types[0]))
120 };
121 struct types vector_types[] = {
122 /* vector-defs.h typedefs */
123 { "v8qi", TYPE_OTHER, 0, 0 },
124 { "v16qi", TYPE_OTHER, 0, 0 },
125 { "v2hi", TYPE_OTHER, 0, 0 },
126 { "v4hi", TYPE_OTHER, 0, 0 },
127 { "v8hi", TYPE_OTHER, 0, 0 },
128 { "v2si", TYPE_OTHER, 0, 0 },
129 { "v4si", TYPE_OTHER, 0, 0 },
130 { "v1di", TYPE_OTHER, 0, 0 },
131 { "v2di", TYPE_OTHER, 0, 0 },
132 { "v2sf", TYPE_OTHER, 0, 0 },
133 { "v4sf", TYPE_OTHER, 0, 0 },
134 { "v16sf", TYPE_OTHER, 0, 0 },
135 { "v2df", TYPE_OTHER, 0, 0 },
136 { "u8qi", TYPE_OTHER, 0, 0 },
137 { "u16qi", TYPE_OTHER, 0, 0 },
138 { "u2hi", TYPE_OTHER, 0, 0 },
139 { "u4hi", TYPE_OTHER, 0, 0 },
140 { "u8hi", TYPE_OTHER, 0, 0 },
141 { "u2si", TYPE_OTHER, 0, 0 },
142 { "u4si", TYPE_OTHER, 0, 0 },
143 { "u1di", TYPE_OTHER, 0, 0 },
144 { "u2di", TYPE_OTHER, 0, 0 },
145 { "u2sf", TYPE_OTHER, 0, 0 },
146 { "u4sf", TYPE_OTHER, 0, 0 },
147 { "u16sf", TYPE_OTHER, 0, 0 },
148 { "u2df", TYPE_OTHER, 0, 0 },
149 { "__m64", TYPE_OTHER, 0, 0 },
150 { "__m128", TYPE_OTHER, 0, 0 }
151 #define NVTYPES2 (sizeof (vector_types) / sizeof (vector_types[0]))
152 };
153 
154 struct types bitfld_types[NTYPES2];
155 int n_bitfld_types;
156 
157 enum ETYPE
158 {
159   ETYPE_TYPE,
160   ETYPE_ARRAY,
161   ETYPE_BITFLD,
162   ETYPE_STRUCT,
163   ETYPE_UNION,
164   ETYPE_STRUCT_ARRAY,
165   ETYPE_UNION_ARRAY
166 };
167 
168 struct entry
169 {
170 #ifdef __GNUC__
171   enum ETYPE etype : 8;
172 #else
173   unsigned char etype;
174 #endif
175   unsigned short len;
176   unsigned char arr_len;
177   struct types *type;
178   const char *attrib;
179   /* Used to chain together entries in the hash table.  */
180   struct entry *next;
181 };
182 
183 /* A prime number giving the number of slots in the hash table.  */
184 #define HASH_SIZE 32749
185 static struct entry *hash_table[HASH_SIZE];
186 
187 static int idx, limidx, output_one;
188 static const char *destdir;
189 static const char *srcdir;
190 FILE *outfile;
191 
192 void
switchfiles(int fields)193 switchfiles (int fields)
194 {
195   static int filecnt;
196   static char *destbuf, *destptr;
197   ++filecnt;
198   if (outfile)
199     fclose (outfile);
200   if (output_one)
201     {
202       outfile = stdout;
203       return;
204     }
205   if (destbuf == NULL)
206     {
207       size_t len = strlen (destdir);
208       destbuf = malloc (len + 20);
209       if (!destbuf)
210 	abort ();
211       memcpy (destbuf, destdir, len);
212       if (!len || destbuf[len - 1] != '/')
213 	destbuf[len++] = '/';
214       destptr = destbuf + len;
215     }
216   sprintf (destptr, "t%03d_main.m", filecnt);
217   outfile = fopen (destbuf, "w");
218   if (outfile == NULL)
219     {
220     fail:
221       fputs ("failed to create test files\n", stderr);
222       exit (1);
223     }
224   /* FIXME: these tests should not be xfailed on aix but they are because
225      libobjc uses GCC's headers for trying to find the struct layout but it
226      gets it wrong.  */
227   if (filecnt == 2
228       || filecnt == 3
229       || filecnt == 4
230       || filecnt == 6
231       || filecnt == 7
232       || filecnt == 8
233       || filecnt == 11
234       || filecnt == 12
235       || filecnt == 15
236       || filecnt == 22)
237      {
238       fprintf (outfile, "\
239 /* { dg-do run { xfail { powerpc*-*-aix* } } } */\n\
240 /* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
241      }
242   /* FIXME: these should not be xfailed but they are because
243      of bugs in libobjc and the objc front-end.  25 is because
244      vectors are not encoded.  The rest are because or zero sized
245      arrays are encoded as pointers.  See PR objc/25361.  */
246   else if (filecnt == 25 || (filecnt >= 27 && filecnt <= 29))
247     {
248       fprintf (outfile, "\
249 /* { dg-do run { xfail { { i?86-*-* x86_64-*-* } || { powerpc*-apple-darwin* && ilp32 } } } } */\n\
250 /* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
251     }
252   else if (filecnt >= 30)
253     {
254       fprintf (outfile, "\
255 /* { dg-do run { xfail { i?86-*-* x86_64-*-* } } } */\n\
256 /* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
257     }
258   else
259     {
260       fprintf (outfile, "\
261 /* { dg-do run } */\n\
262 /* { dg-options \"-w -I%s -fgnu-runtime\" } */\n", srcdir);
263     }
264   fprintf(outfile, "#include <objc/runtime.h> \n\
265 #include \"struct-layout-1.h\"\n\
266 \n\
267 int fails; \n\
268 #define TX(n, type, attrs, fields, ops)                         \\\n\
269 type S##n { fields } attrs;                                     \\\n\
270 void test##n (void)                                             \\\n\
271 {                                                               \\\n\
272   char *encoding = @encode (type S##n);				\\\n\
273   if (objc_sizeof_type (encoding) != sizeof(type S##n)) 	\\\n\
274     {   	                                                \\\n\
275       fails ++;                                                 \\\n\
276       printf(#type \" { \" #fields \"} size is %%u, but is calulated as %%u\\n\", \\\n\
277       	      sizeof(type S##n), objc_sizeof_type (encoding));  \\\n\
278     }           	                                        \\\n\
279   if (objc_alignof_type (encoding) != __alignof__ (type S##n)) 	\\\n\
280     {   	                                                \\\n\
281       fails ++;                                                 \\\n\
282       printf(#type \" { \" #fields \"} align is %%u, but is calulated as %%u\\n\", \\\n\
283       	      __alignof__ (type S##n), objc_alignof_type (encoding));  \\\n\
284     }           	                                        \\\n\
285 }\n\
286 #include \"t%03d_test.h\"\n\
287 #undef TX\n\
288 \n\
289 int main (void)\n\
290 {\n\
291 #define TX(n, type, attrs, fields, ops)   test##n ();\n\
292 #include \"t%03d_test.h\"\n\
293 #undef TX\n\
294   if (fails)\n\
295     {\n\
296       fflush (stdout);\n\
297       abort ();\n\
298     }\n\
299   exit (0);\n\
300 }\n", filecnt, filecnt);
301   fclose (outfile);
302   sprintf (destptr, "t%03d_test.h", filecnt);
303   outfile = fopen (destbuf, "w");
304   if (outfile == NULL)
305     goto fail;
306   if (fields <= 2)
307     limidx = idx + 300;
308   else if (fields <= 4)
309     limidx = idx + 200;
310   else if (fields <= 6)
311     limidx = idx + 100;
312   else
313     limidx = idx + 50;
314 }
315 
316 unsigned long long int
getrandll(void)317 getrandll (void)
318 {
319   unsigned long long int ret;
320   ret = generate_random () & 0xffffff;
321   ret |= (generate_random () & 0xffffffLL) << 24;
322   ret |= ((unsigned long long int) generate_random ()) << 48;
323   return ret;
324 }
325 
326 int
subfield(struct entry * e,char * letter)327 subfield (struct entry *e, char *letter)
328 {
329   int i, type;
330   char buf[20];
331   const char *p;
332   switch (e[0].etype)
333     {
334     case ETYPE_STRUCT:
335     case ETYPE_UNION:
336     case ETYPE_STRUCT_ARRAY:
337     case ETYPE_UNION_ARRAY:
338       type = e[0].attrib ? 1 + (generate_random () & 3) : 0;
339       if (e[0].etype == ETYPE_STRUCT || e[0].etype == ETYPE_STRUCT_ARRAY)
340 	p = "struct";
341       else
342 	p = "union";
343       if (e[0].etype == ETYPE_STRUCT_ARRAY || e[0].etype == ETYPE_UNION_ARRAY)
344 	{
345 	  if (e[0].arr_len == 255)
346 	    snprintf (buf, 20, "%c[]", *letter);
347 	  else
348 	    snprintf (buf, 20, "%c[%d]", *letter, e[0].arr_len);
349 	}
350       else
351         {
352           buf[0] = *letter;
353           buf[1] = '\0';
354         }
355       ++*letter;
356       switch (type)
357         {
358         case 0:
359         case 3:
360         case 4:
361           fprintf (outfile, "%s{", p);
362           break;
363         case 1:
364           fprintf (outfile, "%s %s{", e[0].attrib, p);
365           break;
366         case 2:
367           fprintf (outfile, "%s %s{", p, e[0].attrib);
368           break;
369         }
370 
371       for (i = 1; i <= e[0].len; )
372 	i += subfield (e + i, letter);
373 
374       switch (type)
375         {
376         case 0:
377         case 1:
378         case 2:
379           fprintf (outfile, "}%s;", buf);
380           break;
381 	case 3:
382 	  fprintf (outfile, "}%s %s;", e[0].attrib, buf);
383 	  break;
384 	case 4:
385 	  fprintf (outfile, "}%s %s;", buf, e[0].attrib);
386 	  break;
387         }
388       return 1 + e[0].len;
389     case ETYPE_TYPE:
390     case ETYPE_ARRAY:
391       if (e[0].etype == ETYPE_ARRAY)
392 	{
393 	  if (e[0].arr_len == 255)
394 	    snprintf (buf, 20, "%c[]", *letter);
395 	  else
396 	    snprintf (buf, 20, "%c[%d]", *letter, e[0].arr_len);
397 	}
398       else
399         {
400           buf[0] = *letter;
401           buf[1] = '\0';
402         }
403       ++*letter;
404       if (e[0].attrib)
405 	switch (generate_random () % 3)
406           {
407           case 0:
408             fprintf (outfile, "%s %s %s;", e[0].attrib, e[0].type->name, buf);
409             break;
410           case 1:
411             fprintf (outfile, "%s %s %s;", e[0].type->name, e[0].attrib, buf);
412             break;
413           case 2:
414             fprintf (outfile, "%s %s %s;", e[0].type->name, buf, e[0].attrib);
415             break;
416           }
417       else
418 	fprintf (outfile, "%s %s;", e[0].type->name, buf);
419       return 1;
420     case ETYPE_BITFLD:
421       if (e[0].len == 0)
422 	{
423 	  if (e[0].attrib)
424 	    switch (generate_random () % 3)
425 	      {
426 	      case 0:
427 		fprintf (outfile, "%s %s:0;", e[0].attrib, e[0].type->name);
428 		break;
429 	      case 1:
430 		fprintf (outfile, "%s %s:0;", e[0].type->name, e[0].attrib);
431 		break;
432 	      case 2:
433 		fprintf (outfile, "%s:0 %s;", e[0].type->name, e[0].attrib);
434 		break;
435 	      }
436 	  else
437 	    fprintf (outfile, "%s:0;", e[0].type->name);
438 	  ++*letter;
439 	  return 1;
440 	}
441       switch (e[0].type->bitfld)
442 	{
443 	case 'C':
444 	case 'S':
445 	case 'I':
446 	case 'L':
447 	case 'Q':
448 	  snprintf (buf, 20, "B%cN(%d)", e[0].type->bitfld, e[0].len);
449 	  break;
450 	case 'B':
451 	case ' ':
452 	  snprintf (buf, 20, "%d", e[0].len);
453 	  break;
454 	default:
455 	  abort ();
456 	}
457       if (e[0].attrib)
458 	switch (generate_random () % 3)
459 	  {
460 	  case 0:
461 	    fprintf (outfile, "%s %s %c:%s;", e[0].attrib, e[0].type->name,
462 		     *letter, buf);
463 	    break;
464 	  case 1:
465 	    fprintf (outfile, "%s %s %c:%s;", e[0].type->name, e[0].attrib,
466 		     *letter, buf);
467 	    break;
468 	  case 2:
469 	    fprintf (outfile, "%s %c:%s %s;", e[0].type->name, *letter,
470 		     buf, e[0].attrib);
471 	    break;
472 	  }
473       else
474 	fprintf (outfile, "%s %c:%s;", e[0].type->name, *letter, buf);
475       ++*letter;
476       return 1;
477     default:
478       abort ();
479   }
480 }
481 
482 char namebuf[1024];
483 
484 void
output_FNB(char mode,struct entry * e)485 output_FNB (char mode, struct entry *e)
486 {
487   unsigned long long int l1, l2, m;
488   int signs = 0;
489   const char *p, *q;
490 
491   if (e->type->type == TYPE_OTHER)
492     {
493       if (mode == 'B')
494         abort ();
495       fprintf (outfile, "N(%d,%s)", idx, namebuf);
496       return;
497     }
498   fprintf (outfile, "%c(%d,%s,", mode, idx, namebuf);
499   l1 = getrandll ();
500   l2 = getrandll ();
501   switch (e->type->type)
502     {
503     case TYPE_INT:
504       signs = generate_random () & 3;
505       m = e->type->maxval;
506       if (mode == 'B')
507 	m &= e->len > 1 ? (1ULL << (e->len - 1)) - 1 : 1;
508       l1 &= m;
509       l2 &= m;
510       fprintf (outfile, "%s%llu%s,%s%llu%s",
511 	       (signs & 1) ? "-" : "", l1, l1 > 2147483647 ? "LL" : "",
512 	       (signs & 2) ? "-" : "", l2, l2 > 2147483647 ? "LL" : "");
513       break;
514     case TYPE_UINT:
515       m = e->type->maxval;
516       if (mode == 'B')
517 	m &= (1ULL << e->len) - 1;
518       l1 &= m;
519       l2 &= m;
520       fprintf (outfile, "%lluU%s,%lluU%s", l1, l1 > 4294967295U ? "LL" : "",
521 	       l2, l2 > 4294967295U ? "LL" : "");
522       break;
523     case TYPE_FLOAT:
524       l1 &= 0xffffff;
525       l2 &= 0xffffff;
526       signs = generate_random () & 3;
527       fprintf (outfile, "%s%f,%s%f", (signs & 1) ? "-" : "",
528 	       ((double) l1) / 64, (signs & 2) ? "-" : "", ((double) l2) / 64);
529       break;
530     case TYPE_CINT:
531       signs = generate_random () & 3;
532       l1 &= e->type->maxval;
533       l2 &= e->type->maxval;
534       fprintf (outfile, "CINT(%s%llu%s,%s%llu%s),",
535 	       (signs & 1) ? "-" : "", l1, l1 > 2147483647 ? "LL" : "",
536 	       (signs & 2) ? "-" : "", l2, l2 > 2147483647 ? "LL" : "");
537       signs = generate_random () & 3;
538       l1 = getrandll ();
539       l2 = getrandll ();
540       l1 &= e->type->maxval;
541       l2 &= e->type->maxval;
542       fprintf (outfile, "CINT(%s%llu%s,%s%llu%s)",
543 	       (signs & 1) ? "-" : "", l1, l1 > 2147483647 ? "LL" : "",
544 	       (signs & 2) ? "-" : "", l2, l2 > 2147483647 ? "LL" : "");
545       break;
546     case TYPE_CUINT:
547       l1 &= e->type->maxval;
548       l2 &= e->type->maxval;
549       fprintf (outfile, "CINT(%lluU%s,%lluU%s),",
550 	       l1, l1 > 4294967295U ? "LL" : "",
551 	       l2, l2 > 4294967295U ? "LL" : "");
552       l1 = getrandll ();
553       l2 = getrandll ();
554       l1 &= e->type->maxval;
555       l2 &= e->type->maxval;
556       fprintf (outfile, "CINT(%lluU%s,%lluU%s)",
557 	       l1, l1 > 4294967295U ? "LL" : "",
558 	       l2, l2 > 4294967295U ? "LL" : "");
559       break;
560     case TYPE_CFLOAT:
561       l1 &= 0xffffff;
562       l2 &= 0xffffff;
563       signs = generate_random () & 3;
564       fprintf (outfile, "CDBL(%s%f,%s%f),",
565 	       (signs & 1) ? "-" : "", ((double) l1) / 64,
566 	       (signs & 2) ? "-" : "", ((double) l2) / 64);
567       l1 = getrandll ();
568       l2 = getrandll ();
569       l1 &= 0xffffff;
570       l2 &= 0xffffff;
571       signs = generate_random () & 3;
572       fprintf (outfile, "CDBL(%s%f,%s%f)",
573 	       (signs & 1) ? "-" : "", ((double) l1) / 64,
574 	       (signs & 2) ? "-" : "", ((double) l2) / 64);
575       break;
576     case TYPE_UENUM:
577       if (e->type->maxval == 0)
578 	fputs ("e0_0,e0_0", outfile);
579       else if (e->type->maxval == 1)
580         fprintf (outfile, "e1_%lld,e1_%lld", l1 & 1, l2 & 1);
581       else
582         {
583 	  p = strchr (e->type->name, '\0');
584 	  while (--p >= e->type->name && *p >= '0' && *p <= '9');
585 	  p++;
586           l1 %= 7;
587           l2 %= 7;
588           if (l1 > 3)
589             l1 += e->type->maxval - 6;
590           if (l2 > 3)
591             l2 += e->type->maxval - 6;
592 	  fprintf (outfile, "e%s_%lld,e%s_%lld", p, l1, p, l2);
593         }
594       break;
595     case TYPE_SENUM:
596       p = strchr (e->type->name, '\0');
597       while (--p >= e->type->name && *p >= '0' && *p <= '9');
598       p++;
599       l1 %= 7;
600       l2 %= 7;
601       fprintf (outfile, "e%s_%s%lld,e%s_%s%lld",
602 	       p, l1 < 3 ? "m" : "",
603 	       l1 == 3 ? 0LL : e->type->maxval - (l1 & 3),
604 	       p, l2 < 3 ? "m" : "",
605 	       l2 == 3 ? 0LL : e->type->maxval - (l2 & 3));
606       break;
607     case TYPE_PTR:
608       l1 %= 256;
609       l2 %= 256;
610       fprintf (outfile, "(%s)&intarray[%lld],(%s)&intarray[%lld]",
611 	       e->type->name, l1, e->type->name, l2);
612       break;
613     case TYPE_FNPTR:
614       l1 %= 10;
615       l2 %= 10;
616       fprintf (outfile, "fn%lld,fn%lld", l1, l2);
617       break;
618     default:
619       abort ();
620     }
621   fputs (")", outfile);
622 }
623 
624 int
subvalues(struct entry * e,char * p,char * letter)625 subvalues (struct entry *e, char *p, char *letter)
626 {
627   int i, j;
628   char *q;
629   if (p >= namebuf + sizeof (namebuf) - 32)
630     abort ();
631   p[0] = *letter;
632   p[1] = '\0';
633   q = p + 1;
634   switch (e[0].etype)
635     {
636     case ETYPE_STRUCT_ARRAY:
637     case ETYPE_UNION_ARRAY:
638       if (e[0].arr_len == 0 || e[0].arr_len == 255)
639 	{
640 	  *letter += 1 + e[0].len;
641 	  return 1 + e[0].len;
642 	}
643       i = generate_random () % e[0].arr_len;
644       snprintf (p, sizeof (namebuf) - (p - namebuf) - 1,
645 		"%c[%d]", *letter, i);
646       q = strchr (p, '\0');
647       /* FALLTHROUGH */
648     case ETYPE_STRUCT:
649     case ETYPE_UNION:
650       *q++ = '.';
651       ++*letter;
652       for (i = 1; i <= e[0].len; )
653 	{
654 	  i += subvalues (e + i, q, letter);
655 	  if (e[0].etype == ETYPE_UNION || e[0].etype == ETYPE_UNION_ARRAY)
656 	    {
657 	      *letter += e[0].len - i + 1;
658 	      break;
659 	    }
660 	}
661       return 1 + e[0].len;
662     case ETYPE_TYPE:
663       ++*letter;
664       output_FNB ('F', e);
665       return 1;
666     case ETYPE_ARRAY:
667       if (e[0].arr_len == 0 || e[0].arr_len == 255)
668 	{
669 	  ++*letter;
670 	  return 1;
671 	}
672       i = generate_random () % e[0].arr_len;
673       snprintf (p, sizeof (namebuf) - (p - namebuf),
674 		"%c[%d]", *letter, i);
675       output_FNB ('F', e);
676       if ((generate_random () & 7) == 0)
677 	{
678 	  j = generate_random () % e[0].arr_len;
679 	  if (i != j)
680 	    {
681 	      snprintf (p, sizeof (namebuf) - (p - namebuf),
682 			"%c[%d]", *letter, j);
683 	      output_FNB ('F', e);
684 	    }
685 	}
686       ++*letter;
687       return 1;
688     case ETYPE_BITFLD:
689       ++*letter;
690       if (e[0].len != 0)
691 	output_FNB ('B', e);
692       return 1;
693     default:
694       return 0;
695     }
696 }
697 
698 /* DERIVED FROM:
699 --------------------------------------------------------------------
700 lookup2.c, by Bob Jenkins, December 1996, Public Domain.
701 hash(), hash2(), hash3, and mix() are externally useful functions.
702 Routines to test the hash are included if SELF_TEST is defined.
703 You can use this free for any purpose.  It has no warranty.
704 --------------------------------------------------------------------
705 */
706 
707 /*
708 --------------------------------------------------------------------
709 mix -- mix 3 32-bit values reversibly.
710 For every delta with one or two bit set, and the deltas of all three
711   high bits or all three low bits, whether the original value of a,b,c
712   is almost all zero or is uniformly distributed,
713 * If mix() is run forward or backward, at least 32 bits in a,b,c
714   have at least 1/4 probability of changing.
715 * If mix() is run forward, every bit of c will change between 1/3 and
716   2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
717 mix() was built out of 36 single-cycle latency instructions in a
718   structure that could supported 2x parallelism, like so:
719       a -= b;
720       a -= c; x = (c>>13);
721       b -= c; a ^= x;
722       b -= a; x = (a<<8);
723       c -= a; b ^= x;
724       c -= b; x = (b>>13);
725       ...
726   Unfortunately, superscalar Pentiums and Sparcs can't take advantage
727   of that parallelism.  They've also turned some of those single-cycle
728   latency instructions into multi-cycle latency instructions.  Still,
729   this is the fastest good hash I could find.  There were about 2^^68
730   to choose from.  I only looked at a billion or so.
731 --------------------------------------------------------------------
732 */
733 /* same, but slower, works on systems that might have 8 byte hashval_t's */
734 #define mix(a,b,c) \
735 { \
736   a -= b; a -= c; a ^= (c>>13); \
737   b -= c; b -= a; b ^= (a<< 8); \
738   c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
739   a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
740   b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
741   c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
742   a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
743   b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
744   c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
745 }
746 
747 /*
748 --------------------------------------------------------------------
749 hash() -- hash a variable-length key into a 32-bit value
750   k     : the key (the unaligned variable-length array of bytes)
751   len   : the length of the key, counting by bytes
752   level : can be any 4-byte value
753 Returns a 32-bit value.  Every bit of the key affects every bit of
754 the return value.  Every 1-bit and 2-bit delta achieves avalanche.
755 About 36+6len instructions.
756 
757 The best hash table sizes are powers of 2.  There is no need to do
758 mod a prime (mod is sooo slow!).  If you need less than 32 bits,
759 use a bitmask.  For example, if you need only 10 bits, do
760   h = (h & hashmask(10));
761 In which case, the hash table should have hashsize(10) elements.
762 
763 If you are hashing n strings (ub1 **)k, do it like this:
764   for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
765 
766 By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
767 code any way you wish, private, educational, or commercial.  It's free.
768 
769 See http://burtleburtle.net/bob/hash/evahash.html
770 Use for hash table lookup, or anything where one collision in 2^32 is
771 acceptable.  Do NOT use for cryptographic purposes.
772 --------------------------------------------------------------------
773 */
774 
775 static hashval_t
iterative_hash(const void * k_in,register size_t length,register hashval_t initval)776 iterative_hash (const void *k_in /* the key */,
777                 register size_t  length /* the length of the key */,
778                 register hashval_t initval /* the previous hash, or
779                                               an arbitrary value */)
780 {
781   register const unsigned char *k = (const unsigned char *)k_in;
782   register hashval_t a,b,c,len;
783 
784   /* Set up the internal state */
785   len = length;
786   a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
787   c = initval;           /* the previous hash value */
788 
789   /*---------------------------------------- handle most of the key */
790     while (len >= 12)
791       {
792 	a += (k[0] +((hashval_t)k[1]<<8) +((hashval_t)k[2]<<16) +((hashval_t)k[3]<<24));
793 	b += (k[4] +((hashval_t)k[5]<<8) +((hashval_t)k[6]<<16) +((hashval_t)k[7]<<24));
794 	c += (k[8] +((hashval_t)k[9]<<8) +((hashval_t)k[10]<<16)+((hashval_t)k[11]<<24));
795 	mix(a,b,c);
796 	k += 12; len -= 12;
797       }
798 
799   /*------------------------------------- handle the last 11 bytes */
800   c += length;
801   switch(len)              /* all the case statements fall through */
802     {
803     case 11: c+=((hashval_t)k[10]<<24);
804     case 10: c+=((hashval_t)k[9]<<16);
805     case 9 : c+=((hashval_t)k[8]<<8);
806       /* the first byte of c is reserved for the length */
807     case 8 : b+=((hashval_t)k[7]<<24);
808     case 7 : b+=((hashval_t)k[6]<<16);
809     case 6 : b+=((hashval_t)k[5]<<8);
810     case 5 : b+=k[4];
811     case 4 : a+=((hashval_t)k[3]<<24);
812     case 3 : a+=((hashval_t)k[2]<<16);
813     case 2 : a+=((hashval_t)k[1]<<8);
814     case 1 : a+=k[0];
815       /* case 0: nothing left to add */
816     }
817   mix(a,b,c);
818   /*-------------------------------------------- report the result */
819   return c;
820 }
821 
822 hashval_t
e_hash(const void * a)823 e_hash (const void *a)
824 {
825   const struct entry *e = a;
826   hashval_t ret = 0;
827   int i;
828 
829   if (e[0].etype != ETYPE_STRUCT && e[0].etype != ETYPE_UNION)
830     abort ();
831   for (i = 0; i <= e[0].len; ++i)
832     {
833       int attriblen;
834       ret = iterative_hash (&e[i], offsetof (struct entry, attrib), ret);
835       attriblen = e[i].attrib ? strlen (e[i].attrib) : -1;
836       ret = iterative_hash (&attriblen, sizeof (int), ret);
837       if (e[i].attrib)
838         ret = iterative_hash (e[i].attrib, attriblen, ret);
839     }
840   return ret;
841 }
842 
843 int
e_eq(const void * a,const void * b)844 e_eq (const void *a, const void *b)
845 {
846   const struct entry *ea = a, *eb = b;
847   int i;
848   if (ea[0].etype != ETYPE_STRUCT && ea[0].etype != ETYPE_UNION)
849     abort ();
850   if (ea[0].len != eb[0].len)
851     return 0;
852   for (i = 0; i <= ea[0].len; ++i)
853     {
854       if (ea[i].etype != eb[i].etype
855 	  || ea[i].len != eb[i].len
856 	  || ea[i].arr_len != eb[i].arr_len
857 	  || ea[i].type != eb[i].type)
858 	return 0;
859       if ((ea[i].attrib == NULL) ^ (eb[i].attrib == NULL))
860 	return 0;
861       if (ea[i].attrib && strcmp (ea[i].attrib, eb[i].attrib) != 0)
862 	return 0;
863     }
864   return 1;
865 }
866 
867 static int
e_exists(const struct entry * e)868 e_exists (const struct entry *e)
869 {
870   struct entry *h;
871   hashval_t hval;
872 
873   hval = e_hash (e);
874   for (h = hash_table[hval % HASH_SIZE]; h; h = h->next)
875     if (e_eq (e, h))
876       return 1;
877   return 0;
878 }
879 
880 static void
e_insert(struct entry * e)881 e_insert (struct entry *e)
882 {
883   hashval_t hval;
884 
885   hval = e_hash (e);
886   e->next = hash_table[hval % HASH_SIZE];
887   hash_table[hval % HASH_SIZE] = e;
888 }
889 
890 void
output(struct entry * e)891 output (struct entry *e)
892 {
893   int i;
894   char c;
895   struct entry *n;
896   const char *skip_cint = "";
897 
898   if (e[0].etype != ETYPE_STRUCT && e[0].etype != ETYPE_UNION)
899     abort ();
900 
901   if (e_exists (e))
902     return;
903 
904   n = (struct entry *) malloc ((e[0].len + 1) * sizeof (struct entry));
905   memcpy (n, e, (e[0].len + 1) * sizeof (struct entry));
906   e_insert (n);
907 
908   if (idx == limidx)
909     switchfiles (e[0].len);
910 
911   for (i = 1; i <= e[0].len; ++i)
912     if ((e[i].etype == ETYPE_TYPE || e[i].etype == ETYPE_ARRAY)
913 	&& (e[i].type->type == TYPE_CINT || e[i].type->type == TYPE_CUINT))
914       break;
915   if (i <= e[0].len)
916     skip_cint = "CI";
917   if (e[0].attrib)
918     fprintf (outfile, (generate_random () & 1)
919 	     ? "TX%s(%d,%s %s,," : "TX%s(%d,%s,%s,", skip_cint,
920 	     idx, e[0].etype == ETYPE_STRUCT ? "struct" : "union",
921 	     e[0].attrib);
922   else if (e[0].etype == ETYPE_STRUCT)
923     fprintf (outfile, "T%s(%d,", skip_cint, idx);
924   else
925     fprintf (outfile, "U%s(%d,", skip_cint, idx);
926   c = 'a';
927   for (i = 1; i <= e[0].len; )
928     i += subfield (e + i, &c);
929   fputs (",", outfile);
930   c = 'a';
931   for (i = 1; i <= e[0].len; )
932     {
933       i += subvalues (e + i, namebuf, &c);
934       if (e[0].etype == ETYPE_UNION)
935         break;
936     }
937   fputs (")\n", outfile);
938   if (output_one && idx == limidx)
939     exit (0);
940   ++idx;
941 }
942 
943 enum FEATURE
944 {
945   FEATURE_VECTOR = 1,
946   FEATURE_COMPLEX = 2,
947   FEATURE_ZEROARRAY = 8,
948   FEATURE_ZEROBITFLD = 16,
949   ALL_FEATURES = FEATURE_COMPLEX | FEATURE_VECTOR | FEATURE_ZEROARRAY
950 		 | FEATURE_ZEROBITFLD
951 };
952 
953 void
singles(enum FEATURE features)954 singles (enum FEATURE features)
955 {
956   struct entry e[2];
957   int i;
958   memset (e, 0, sizeof (e));
959   e[0].etype = ETYPE_STRUCT;
960   output (e);
961   e[0].etype = ETYPE_UNION;
962   output (e);
963   e[0].len = 1;
964   e[0].attrib = NULL;
965   for (i = 0; i < NTYPES2; ++i)
966     {
967       e[0].etype = ETYPE_STRUCT;
968       e[1].etype = ETYPE_TYPE;
969       e[1].type = &base_types[i];
970       output (e);
971       e[0].etype = ETYPE_UNION;
972       output (e);
973     }
974   if (features & FEATURE_COMPLEX)
975     for (i = 0; i < NCTYPES2; ++i)
976       {
977 	e[0].etype = ETYPE_STRUCT;
978 	e[1].etype = ETYPE_TYPE;
979 	e[1].type = &complex_types[i];
980 	output (e);
981 	e[0].etype = ETYPE_UNION;
982 	output (e);
983       }
984   if (features & FEATURE_VECTOR)
985     for (i = 0; i < NVTYPES2; ++i)
986       {
987 	e[0].etype = ETYPE_STRUCT;
988 	e[1].etype = ETYPE_TYPE;
989 	e[1].type = &vector_types[i];
990 	output (e);
991 	e[0].etype = ETYPE_UNION;
992 	output (e);
993       }
994 }
995 
996 void
choose_type(enum FEATURE features,struct entry * e,int r,int in_array)997 choose_type (enum FEATURE features, struct entry *e, int r, int in_array)
998 {
999   int i;
1000 
1001   i = NTYPES2 - NTYPES1;
1002   if (features & FEATURE_COMPLEX)
1003     i += NCTYPES2;
1004   if (features & FEATURE_VECTOR)
1005     i += NVTYPES2;
1006   r >>= 2;
1007   r %= i;
1008   if (r < NTYPES2 - NTYPES1)
1009     e->type = &base_types[r + NTYPES1];
1010   r -= NTYPES2 - NTYPES1;
1011   if (e->type == NULL && (features & FEATURE_COMPLEX))
1012     {
1013       if (r < NCTYPES2)
1014 	e->type = &complex_types[r];
1015       r -= NCTYPES2;
1016     }
1017   if (e->type == NULL && (features & FEATURE_VECTOR))
1018     {
1019       if (r < NVTYPES2)
1020 	e->type = &vector_types[r];
1021       r -= NVTYPES2;
1022     }
1023     if (e->type == NULL)
1024     abort ();
1025 }
1026 
1027 /* This is from gcc.c-torture/execute/builtin-bitops-1.c.  */
1028 static int
my_ffsll(unsigned long long x)1029 my_ffsll (unsigned long long x)
1030 {
1031   int i;
1032   if (x == 0)
1033     return 0;
1034   /* We've tested LLONG_MAX for 64 bits so this should be safe.  */
1035   for (i = 0; i < 64; i++)
1036     if (x & (1ULL << i))
1037       break;
1038   return i + 1;
1039 }
1040 
1041 void
generate_fields(enum FEATURE features,struct entry * e,struct entry * parent,int len)1042 generate_fields (enum FEATURE features, struct entry *e, struct entry *parent,
1043 		 int len)
1044 {
1045   int r, i, j, ret = 1, n, incr, sametype;
1046 
1047   for (n = 0; n < len; n += incr)
1048     {
1049       r = generate_random ();
1050       /* 50% ETYPE_TYPE base_types NTYPES1
1051 	 12.5% ETYPE_TYPE other
1052 	 12.5% ETYPE_ARRAY
1053 	 12.5% ETYPE_BITFLD
1054 	 12.5% ETYPE_STRUCT|ETYPE_UNION|ETYPE_STRUCT_ARRAY|ETYPE_UNION_ARRAY */
1055       i = (r & 7);
1056       r >>= 3;
1057       incr = 1;
1058       switch (i)
1059 	{
1060 	case 6: /* BITfields disabled for now as _Bool bitfields are broken. */
1061 	case 0:
1062 	case 1:
1063 	case 2:
1064 	case 3:
1065 	  e[n].etype = ETYPE_TYPE;
1066 	  e[n].type = &base_types[r % NTYPES1];
1067 	  break;
1068 	case 4:
1069 	  e[n].etype = ETYPE_TYPE;
1070 	  choose_type (features, &e[n], r, 0);
1071 	  break;
1072 	case 5:
1073 	  e[n].etype = ETYPE_ARRAY;
1074 	  i = r & 1;
1075 	  r >>= 1;
1076 	  if (i)
1077 	    e[n].type = &base_types[r % NTYPES1];
1078 	  else
1079 	    choose_type (features, &e[n], r, 1);
1080 	  r = generate_random ();
1081 	  if ((features & FEATURE_ZEROARRAY) && (r & 3) == 0)
1082 	    {
1083 	      e[n].arr_len = 0;
1084 	      if (n == len - 1 && (r & 4)
1085 		  && (parent->etype == ETYPE_STRUCT
1086 		      || parent->etype == ETYPE_STRUCT_ARRAY))
1087 		{
1088 		  int k;
1089 		  for (k = 0; k < n; ++k)
1090 		    if (e[k].etype != ETYPE_BITFLD || e[k].len)
1091 		      {
1092 			e[n].arr_len = 255;
1093 			break;
1094 		      }
1095 		}
1096 	    }
1097 	  else if ((r & 3) != 3)
1098 	    e[n].arr_len = (r >> 2) & 7;
1099 	  else
1100 	    e[n].arr_len = (r >> 2) & 31;
1101 	  break;
1102 #if 0
1103 	case 6:
1104 	  sametype = 1;
1105 	  switch (r & 7)
1106 	    {
1107 	    case 0:
1108 	    case 1:
1109 	    case 2:
1110 	      break;
1111 	    case 3:
1112 	    case 4:
1113 	    case 5:
1114 	      incr = 1 + (r >> 3) % (len - n);
1115 	      break;
1116 	    case 6:
1117 	    case 7:
1118 	      sametype = 0;
1119 	      incr = 1 + (r >> 3) % (len - n);
1120 	      break;
1121 	    }
1122 	  for (j = n; j < n + incr; ++j)
1123 	    {
1124 	      int mi, ma;
1125 
1126 	      e[j].etype = ETYPE_BITFLD;
1127 	      if (j == n || !sametype)
1128 		{
1129 		  r = generate_random ();
1130 		  r >>= 2;
1131 		  e[j].type
1132 		      = &bitfld_types[r % n_bitfld_types];
1133 		}
1134 	      else
1135 		e[j].type = e[n].type;
1136 	      r = generate_random ();
1137 	      mi = 0;
1138 	      ma = 0;
1139 	      switch (e[j].type->bitfld)
1140 	        {
1141 	        case 'C': ma = 8; break;
1142 	        case 'S': ma = 16; break;
1143 	        case 'I': ma = 32; break;
1144 	        case 'L':
1145 	        case 'Q': ma = 64; break;
1146 	        case 'B': ma = 1; break;
1147 	        case ' ':
1148 		  if (e[j].type->type == TYPE_UENUM)
1149 		    mi = my_ffsll (e[j].type->maxval + 1) - 1;
1150 		  else if (e[j].type->type == TYPE_SENUM)
1151 		    mi = my_ffsll (e[j].type->maxval + 1);
1152 		  else
1153 		    abort ();
1154 		  if (!mi)
1155 		    mi = 1;
1156 		  if (mi <= 32)
1157 		    ma = 32;
1158 		  else
1159 		    ma = 64;
1160 		  break;
1161 		default:
1162 		  abort ();
1163 	        }
1164 	      e[j].len = ma + 1;
1165 	      if (sametype && (r & 3) == 0 && ma > 1)
1166 		{
1167 		  int sum = 0, k;
1168 		  for (k = n; k < j; ++k)
1169 		    sum += e[k].len;
1170 		  sum %= ma;
1171 		  e[j].len = sum ? ma - sum : ma;
1172 		}
1173 	      r >>= 2;
1174 	      if (! (features & FEATURE_ZEROBITFLD) && mi == 0)
1175 		mi = 1;
1176 	      if (e[j].len < mi || e[j].len > ma)
1177 		e[j].len = mi + (r % (ma + 1 - mi));
1178 	      r >>= 6;
1179 	      if ((features & FEATURE_ZEROBITFLD) && (r & 3) == 0
1180 		  && mi == 0)
1181 		e[j].len = 0;
1182 	    }
1183 	  break;
1184 #endif
1185 	case 7:
1186 	  switch (r & 7)
1187 	    {
1188 	    case 0:
1189 	    case 1:
1190 	    case 2:
1191 	      e[n].etype = ETYPE_STRUCT;
1192 	      break;
1193 	    case 3:
1194 	    case 4:
1195 	      e[n].etype = ETYPE_UNION;
1196 	      break;
1197 	    case 5:
1198 	    case 6:
1199 	      e[n].etype = ETYPE_STRUCT_ARRAY;
1200 	      break;
1201 	    case 7:
1202 	      e[n].etype = ETYPE_UNION_ARRAY;
1203 	      break;
1204 	    }
1205 	  r >>= 3;
1206 	  e[n].len = r % (len - n);
1207 	  incr = 1 + e[n].len;
1208 	  generate_fields (features, &e[n + 1], &e[n], e[n].len);
1209 	  if (e[n].etype == ETYPE_STRUCT_ARRAY
1210 	      || e[n].etype == ETYPE_UNION_ARRAY)
1211 	    {
1212 	      r = generate_random ();
1213 	      if ((features & FEATURE_ZEROARRAY) && (r & 3) == 0)
1214 		{
1215 		  e[n].arr_len = 0;
1216 		  if (n + incr == len && (r & 4)
1217 		      && (parent->etype == ETYPE_STRUCT
1218 			  || parent->etype == ETYPE_STRUCT_ARRAY))
1219 		    {
1220 		      int k;
1221 		      for (k = 0; k < n; ++k)
1222 			if (e[k].etype != ETYPE_BITFLD || e[k].len)
1223 			  {
1224 			    e[n].arr_len = 255;
1225 			    break;
1226 			  }
1227 		    }
1228 		}
1229 	      else if ((r & 3) != 3)
1230 		e[n].arr_len = (r >> 2) & 7;
1231 	      else
1232 		e[n].arr_len = (r >> 2) & 31;
1233 	    }
1234 	  break;
1235 	}
1236     }
1237 }
1238 
1239 void
generate_random_tests(enum FEATURE features,int len)1240 generate_random_tests (enum FEATURE features, int len)
1241 {
1242   struct entry e[len + 1];
1243   int i, r;
1244   if (len > 'z' - 'a' + 1)
1245     abort ();
1246   memset (e, 0, sizeof (e));
1247   r = generate_random ();
1248   if ((r & 7) == 0)
1249     e[0].etype = ETYPE_UNION;
1250   else
1251     e[0].etype = ETYPE_STRUCT;
1252   r >>= 3;
1253   e[0].len = len;
1254   generate_fields (features, &e[1], &e[0], len);
1255   output (e);
1256 }
1257 
1258 struct { const char *name; enum FEATURE f; }
1259 features[] = {
1260 { "normal", 0 },
1261 { "complex", FEATURE_COMPLEX },
1262 { "vector", FEATURE_VECTOR },
1263 { "[0] :0", FEATURE_ZEROARRAY | FEATURE_ZEROBITFLD },
1264 { "complex vector [0]",
1265   FEATURE_COMPLEX | FEATURE_VECTOR | FEATURE_ZEROARRAY }
1266 };
1267 
1268 int
main(int argc,char ** argv)1269 main (int argc, char **argv)
1270 {
1271   int i, j, count, c, n = 3000;
1272   char *optarg;
1273 
1274   if (sizeof (int) != 4 || sizeof (long long) != 8)
1275     return 1;
1276 
1277   i = 1;
1278   while (i < argc)
1279     {
1280       c = '\0';
1281       if (argv[i][0] == '-' && argv[i][2] == '\0')
1282 	c = argv[i][1];
1283       optarg = argv[i + 1];
1284       if (!optarg)
1285 	goto usage;
1286       switch (c)
1287 	{
1288 	case 'n':
1289 	  n = atoi (optarg);
1290 	  break;
1291 	case 'd':
1292 	  destdir = optarg;
1293 	  break;
1294 	case 's':
1295 	  srcdir = optarg;
1296 	  break;
1297 	case 'i':
1298 	  output_one = 1;
1299 	  limidx = atoi (optarg);
1300 	  break;
1301 	default:
1302 	  fprintf (stderr, "unrecognized option %s\n", argv[i]);
1303 	  goto usage;
1304       }
1305       i += 2;
1306     }
1307 
1308   if (output_one)
1309     {
1310       outfile = fopen ("/dev/null", "w");
1311       if (outfile == NULL)
1312         {
1313 	  fputs ("could not open /dev/null", stderr);
1314 	  return 1;
1315         }
1316       n = limidx + 1;
1317     }
1318 
1319   if (destdir == NULL && !output_one)
1320     {
1321     usage:
1322       fprintf (stderr, "Usage:\n\
1323 %s [-s srcdir -d destdir] [-n count] [-i idx]\n\
1324 Either -s srcdir -d destdir or -i idx must be used\n", argv[0]);
1325       return 1;
1326     }
1327 
1328   if (srcdir == NULL && !output_one)
1329     goto usage;
1330 
1331   for (i = 0; i < NTYPES2; ++i)
1332     if (base_types[i].bitfld)
1333       bitfld_types[n_bitfld_types++] = base_types[i];
1334   for (i = 0; i < sizeof (features) / sizeof (features[0]); ++i)
1335     {
1336       int startidx = idx;
1337       if (! output_one)
1338 	limidx = idx;
1339       if (!i)
1340         count = 200;
1341       else
1342         count = 20;
1343       for (j = 1; j <= 9; ++j)
1344         while (idx < startidx + j * count)
1345 	  generate_random_tests (features[i].f, j);
1346       while (idx < startidx + count * 10)
1347 	generate_random_tests (features[i].f, 10 + (generate_random () % 16));
1348     }
1349   for (i = 0; n > 3000 && i < sizeof (features) / sizeof (features[0]); ++i)
1350     {
1351       int startidx;
1352       startidx = idx;
1353       if (! output_one)
1354 	limidx = idx;
1355       singles (features[i].f);
1356       if (!i)
1357 	{
1358 	  count = 1000;
1359 	  while (idx < startidx + 1000)
1360 	    generate_random_tests (features[i].f, 1);
1361 	}
1362       else
1363 	{
1364 	  startidx = idx;
1365 	  count = 100;
1366 	  while (idx < startidx + 100)
1367 	    generate_random_tests (features[i].f, 1);
1368 	}
1369       startidx = idx;
1370       for (j = 2; j <= 9; ++j)
1371 	while (idx < startidx + (j - 1) * count)
1372 	  generate_random_tests (features[i].f, j);
1373       while (idx < startidx + count * 9)
1374         generate_random_tests (features[i].f, 10 + (generate_random () % 16));
1375     }
1376   if (! output_one)
1377     limidx = idx;
1378   while (idx < n)
1379     generate_random_tests (ALL_FEATURES, 1 + (generate_random () % 25));
1380   fclose (outfile);
1381   return 0;
1382 }
1383