OSDN Git Service

* spu.c: Bump to version 0.3; make all space dynamically sized
[pf3gnuchains/pf3gnuchains3x.git] / utils / spu / spu.c
1 /* spu -- A program to make lots of random C/C++ code.
2    Copyright (C) 1993, 1994, 2000 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.  Written by Stan Shebs.
4
5 This file is part of SPU.
6
7 SPU is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING.  If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /* This is a random program generator. */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 char *version_string = "0.3";
29
30 /* These values are the builtin defaults, mainly useful for testing
31    purposes, or if the user is uninterested in setting a value.  */
32
33 #define DEFAULT_NUM_FILES 5
34
35 #define DEFAULT_NUM_HEADER_FILES 1
36
37 #define DEFAULT_NUM_MACROS 10
38
39 #define DEFAULT_NUM_LIB_MACROS 30
40
41 #define DEFAULT_MAX_MACRO_ARGS 5
42
43 #define DEFAULT_NUM_ENUMS 10
44
45 #define DEFAULT_NUM_LIB_ENUMS 30
46
47 #define DEFAULT_NUM_ENUMERATORS 10
48
49 #define DEFAULT_NUM_STRUCTS 10
50
51 #define DEFAULT_NUM_LIB_STRUCTS 30
52
53 #define DEFAULT_NUM_FIELDS 20
54
55 #define DEFAULT_NUM_FUNCTIONS 100
56
57 #define DEFAULT_NUM_LIB_FUNCTIONS 300
58
59 #define DEFAULT_MAX_FUNCTION_ARGS 8
60
61 #define DEFAULT_FUNCTION_LENGTH 20
62
63 #define DEFAULT_FUNCTION_DEPTH 3
64
65 #define DEFAULT_LIB_PERCENT 10
66
67 /* Generic hash table.  */
68
69 struct hash_entry
70 {
71   char *val;
72   struct hash_entry *next;
73 };
74
75 struct hash_table
76 {
77   struct hash_entry *entries[253];
78   int numadds;
79 };
80
81 struct macro_desc
82 {
83   char *name;
84   int numargs;
85   char **args;
86   int use;
87 };
88
89 struct enumerator_desc
90 {
91   char *name;
92 };
93
94 struct enum_desc
95 {
96   char *name;
97   int num_enumerators;
98   struct enumerator_desc *enumerators;
99   int use;
100 };
101
102 struct field_desc
103 {
104   int type;
105   char *name;
106 };
107
108 struct struct_desc
109 {
110   char *name;
111   int numfields;
112   struct field_desc *fields;
113   int use;
114 };
115
116 /* (should add unions as type of struct) */
117
118 struct type_desc
119 {
120   char *name;
121 };
122
123 struct arg_desc
124 {
125   int type;
126   char *name;
127 };
128
129 struct function_desc
130 {
131   char *name;
132   int numargs;
133   struct arg_desc *args;
134   int use;
135 };
136
137 struct file_desc
138 {
139   char *name;
140 };
141
142 /* Function declarations.  */
143
144 void display_usage (void);
145
146 int hash_string (char *str);
147
148 struct hash_entry *get_hash_entry (void);
149
150 char *add_to_hash_table (char *buf, struct hash_table *table);
151
152 char *get_from_hash_table (char *buf, struct hash_table *table);
153
154 void init_xrandom (int seed);
155
156 int xrandom (int n);
157
158 int probability (int prob);
159
160 char *copy_string (char *str);
161
162 char *xmalloc (int n);
163
164 char *gen_unique_global_name (char *root, int upcase);
165
166 void gen_random_global_name (char *root, char *namebuf);
167
168 char *gen_random_local_name (int n, char **others);
169
170 void create_macros (void);
171
172 void create_macro (struct macro_desc *macrodesc);
173
174 char *gen_new_macro_name (void);
175
176 void create_enums (void);
177
178 void create_enum (struct enum_desc *enumdesc);
179
180 char *gen_random_enumerator_name (void);
181
182 void create_structs (void);
183
184 void create_struct (struct struct_desc *structdesc);
185
186 char *gen_random_field_name (int n);
187
188 void create_functions (void);
189
190 void create_function (struct function_desc *fndesc);
191
192 void write_header_file (int n);
193
194 void write_lib_header_file (void);
195
196 void write_source_file (int n);
197
198 void write_macro (FILE *fp, struct macro_desc *macrodesc);
199
200 void write_enum (FILE *fp, struct enum_desc *enumdesc);
201
202 void write_struct (FILE *fp, struct struct_desc *structdesc);
203
204 void write_function_decl (FILE *fp, struct function_desc *functiondesc);
205
206 void write_function (FILE *fp, int n);
207
208 void write_lib_function (FILE *fp, int n);
209
210 void write_statement (FILE *fp, int depth, int max_depth);
211
212 void write_expression (FILE *fp, int depth, int max_depth);
213
214 void write_makefile (void);
215
216 /* Global variables.  */
217
218 /* The possible languages. */
219
220 enum languages { knr, c, cpp, objc };
221
222 enum languages language = c;
223
224 /* Filename extensions to use with each language type.  */
225
226 char *extensions[] = { "c", "c", "cc", "m" };
227
228 int num_files = DEFAULT_NUM_FILES;
229
230 int num_header_files = DEFAULT_NUM_HEADER_FILES;
231
232 char *file_base_name = "file";
233
234 int num_macros = DEFAULT_NUM_MACROS;
235
236 int num_lib_macros = DEFAULT_NUM_LIB_MACROS;
237
238 int num_enums = DEFAULT_NUM_ENUMS;
239
240 int num_lib_enums = DEFAULT_NUM_LIB_ENUMS;
241
242 int num_enumerators = DEFAULT_NUM_ENUMERATORS;
243
244 int num_structs = DEFAULT_NUM_STRUCTS;
245
246 int num_lib_structs = DEFAULT_NUM_LIB_STRUCTS;
247
248 int num_fields = DEFAULT_NUM_FIELDS;
249
250 int num_functions = DEFAULT_NUM_FUNCTIONS;
251
252 int num_lib_functions = DEFAULT_NUM_LIB_FUNCTIONS;
253
254 int max_function_args = DEFAULT_MAX_FUNCTION_ARGS;
255
256 int function_length = DEFAULT_FUNCTION_LENGTH;
257
258 int function_depth = DEFAULT_FUNCTION_DEPTH;
259
260 /* Percentage of library constructs that will be referenced.  */
261
262 int lib_percent = DEFAULT_LIB_PERCENT;
263
264 int num_functions_per_file;
265
266 /* The amount of commenting in the source.  */
267
268 int commenting = 0;
269
270 /* Hash table for globally visible symbols.  */
271
272 struct hash_table *global_hash_table;
273
274 /* The seed for the random number generator.  */
275
276 int seed = -1;
277
278 /* Space to record info about generated constructs.  */
279
280 struct macro_desc *macros;
281
282 struct macro_desc *lib_macros;
283
284 struct enum_desc *enums;
285
286 struct enum_desc *lib_enums;
287
288 struct struct_desc *structs;
289
290 struct struct_desc *lib_structs;
291
292 struct function_desc *functions;
293
294 struct function_desc *lib_functions;
295
296 int num_computer_terms;
297
298 /* Likely words to appear in names of things.  These must never be
299    valid C/C++ keywords, since they may appear by themselves in some
300    contexts.  */
301
302 char *computerese[] = {
303   "add", "all", "alloc", "allocate", "area", "array", "at",
304   "by", "btree",
305   "count", "create", "cull",
306   "del", "delete_", "desc", "discard", "dismiss",
307   "fill", "find", "fn", "for_",
308   "grok",
309   "last", "line", "lis", "list", "lose",
310   "make", "mod", "modify", "more",
311   "new_", "node", "null", "num",
312   "part", "partial",
313   "query", "queue",
314   "ob", "obj", "object", "of",
315   "pnt", "point", "pos", "position",
316   "rect", "rectangle", "remove", "reset",
317   "see", "set", "shape", "str",
318   "tag", "tree",
319   "vary", "vec", "vect", "vector", "virt", "virtual_",
320   "win", "wind", "window",
321   "zbuf",
322   NULL
323 };
324
325 /* Return a word that commonly appears in programs. */
326
327 char *
328 random_computer_word (void)
329 {
330   if (num_computer_terms == 0)
331     {
332       int i;
333
334       for (i = 0; computerese[i] != NULL; ++i)
335         ;
336       num_computer_terms = i;
337     }
338   return computerese[xrandom (num_computer_terms)];
339 }
340
341 int
342 main (int argc, char **argv)
343 {
344   int i, num;
345   char *arg;
346
347   
348   /* Parse all the arguments. */
349   /* (should check on numeric values) */
350   for (i = 1; i < argc; ++i)
351     {
352       arg = argv[i];
353       if (strcmp(arg, "--basename") == 0)
354         {
355           file_base_name = copy_string(argv[++i]);
356         }
357       else if (strcmp(arg, "--comments") == 0)
358         {
359           num = strtol (argv[++i], NULL, 10);
360           commenting = num;
361         }
362       else if (strcmp(arg, "--enums") == 0)
363         {
364           num = strtol (argv[++i], NULL, 10);
365           num_enums = num;
366         }
367       else if (strcmp(arg, "--enumerators") == 0)
368         {
369           num = strtol (argv[++i], NULL, 10);
370           num_enumerators = num;
371         }
372       else if (strcmp(arg, "--fields") == 0)
373         {
374           num = strtol (argv[++i], NULL, 10);
375           num_fields = num;
376         }
377       else if (strcmp(arg, "--files") == 0)
378         {
379           num = strtol (argv[++i], NULL, 10);
380           num_files = num;
381         }
382       else if (strcmp(arg, "--functions") == 0)
383         {
384           num = strtol (argv[++i], NULL, 10);
385           num_functions = num;
386         }
387       else if (strcmp(arg, "--function-length") == 0)
388         {
389           num = strtol (argv[++i], NULL, 10);
390           function_length = num;
391         }
392       else if (strcmp(arg, "--function-depth") == 0)
393         {
394           num = strtol (argv[++i], NULL, 10);
395           function_depth = num;
396         }
397       else if (strcmp(arg, "--header-files") == 0)
398         {
399           num = strtol (argv[++i], NULL, 10);
400           num_header_files = num;
401         }
402       else if (strcmp(arg, "--help") == 0)
403         {
404           display_usage ();
405           exit (0);
406         }
407       else if (strcmp(arg, "--language") == 0)
408         {
409           if (strcmp (argv[i+1], "c") == 0)
410             language = c;
411           else if (strcmp (argv[i+1], "cpp") == 0)
412             language = cpp;
413           else if (strcmp (argv[i+1], "knr") == 0)
414             language = knr;
415           else if (strcmp (argv[i+1], "objc") == 0)
416             language = objc;
417           ++i;
418         }
419       else if (strcmp(arg, "--lib-enums") == 0)
420         {
421           num = strtol (argv[++i], NULL, 10);
422           num_lib_enums = num;
423         }
424       else if (strcmp(arg, "--lib-functions") == 0)
425         {
426           num = strtol (argv[++i], NULL, 10);
427           num_lib_functions = num;
428         }
429       else if (strcmp(arg, "--lib-macros") == 0)
430         {
431           num = strtol (argv[++i], NULL, 10);
432           num_lib_macros = num;
433         }
434       else if (strcmp(arg, "--lib-structs") == 0)
435         {
436           num = strtol (argv[++i], NULL, 10);
437           num_lib_structs = num;
438         }
439       else if (strcmp(arg, "--macros") == 0)
440         {
441           num = strtol (argv[++i], NULL, 10);
442           num_macros = num;
443         }
444       else if (strcmp(arg, "--seed") == 0)
445         {
446           num = strtol (argv[++i], NULL, 10);
447           seed = num;
448         }
449       else if (strcmp(arg, "--structs") == 0)
450         {
451           num = strtol (argv[++i], NULL, 10);
452           num_structs = num;
453         }
454       else if (strcmp(arg, "--version") == 0)
455         {
456           fprintf (stderr, "SPU program generator version %s\n",
457                    version_string);
458           exit (0);
459         }
460       else
461         {
462           fprintf (stderr, "Usage: \"%s\" not valid, ignored\n", arg);
463           display_usage ();
464         }
465     }
466   init_xrandom (seed);
467   /* Create the definitions of objects internally. */
468   create_macros ();
469   create_enums ();
470   create_structs ();
471   create_functions ();
472   /* Round up the number of functions so each file gets the same
473      number. */
474   num_functions_per_file = (num_functions + num_files - 1) / num_files;
475   /* Write out a bunch of files. */
476   printf ("Writing %d header files...\n", num_header_files);
477   for (i = 0; i < num_header_files; ++i)
478     write_header_file (i);
479   write_lib_header_file ();
480   write_lib_source_file ();
481   printf ("Writing %d files...\n", num_files);
482   for (i = 0; i < num_files; ++i)
483     write_source_file (i);
484   /* Write out a makefile. */
485   write_makefile ();
486   /* Succeed if we actually wrote out a whole program correctly. */
487   exit (0);
488 }
489
490 void
491 display_usage (void)
492 {
493   fprintf (stderr, "Usage: spu [ ... options ... ]\n");
494   fprintf (stderr, "\t--basename str (default \"%s\")\n", "file");
495   fprintf (stderr, "\t--comments n\n");
496   fprintf (stderr, "\t--enums n (default %d)\n", DEFAULT_NUM_ENUMS);
497   fprintf (stderr, "\t--enumerators n (default %d)\n", DEFAULT_NUM_ENUMERATORS);
498   fprintf (stderr, "\t--fields n (default %d)\n", DEFAULT_NUM_FIELDS);
499   fprintf (stderr, "\t--files n (default %d)\n", DEFAULT_NUM_FILES);
500   fprintf (stderr, "\t--functions n (default %d)\n", DEFAULT_NUM_FUNCTIONS);
501   fprintf (stderr, "\t--function-length n (default %d)\n", DEFAULT_FUNCTION_LENGTH);
502   fprintf (stderr, "\t--function-depth n (default %d)\n", DEFAULT_FUNCTION_DEPTH);
503   fprintf (stderr, "\t--header-files n (default %d)\n", DEFAULT_NUM_HEADER_FILES);
504   fprintf (stderr, "\t--help\n");
505   fprintf (stderr, "\t--language c|cpp|knr|objc (default c)\n");
506   fprintf (stderr, "\t--lib-enums n (default %d)\n", DEFAULT_NUM_LIB_ENUMS);
507   fprintf (stderr, "\t--lib-functions n (default %d)\n", DEFAULT_NUM_LIB_FUNCTIONS);
508   fprintf (stderr, "\t--lib-macros n (default %d)\n", DEFAULT_NUM_LIB_MACROS);
509   fprintf (stderr, "\t--lib-structs n (default %d)\n", DEFAULT_NUM_LIB_STRUCTS);
510   fprintf (stderr, "\t--macros n (default %d)\n", DEFAULT_NUM_MACROS);
511   fprintf (stderr, "\t--seed n\n");
512   fprintf (stderr, "\t--structs n (default %d)\n", DEFAULT_NUM_STRUCTS);
513   fprintf (stderr, "\t--version\n");
514 }
515
516 int
517 random_type (void)
518 {
519   return xrandom (3);
520 }
521
522 /* Given a numbered type, return its name.  */
523
524 char *
525 name_from_type (int n)
526 {
527   switch (n)
528     {
529     case 0:
530       return "char";
531     case 1:
532       return "short";
533     }
534   return "int";
535 }
536
537 /* Create basic definitions of macros.  Negative number of arguments
538    means a macros that looks like a constant instead of a function.  */
539
540 void
541 create_macros (void)
542 {
543   int i;
544
545   printf ("Creating %d macros...\n", num_macros);
546   macros =
547     (struct macro_desc *) xmalloc (num_macros * sizeof(struct macro_desc));
548   for (i = 0; i < num_macros; ++i)
549     {
550       create_macro (&(macros[i]));
551     }
552   printf ("Creating %d library macros...\n", num_lib_macros);
553   lib_macros =
554     (struct macro_desc *) xmalloc (num_lib_macros * sizeof(struct macro_desc));
555   for (i = 0; i < num_lib_macros; ++i)
556     {
557       create_macro (&(lib_macros[i]));
558       if (!probability(lib_percent))
559         lib_macros[i].use = 0;
560     }
561 }
562
563 void
564 create_macro (struct macro_desc *macrodesc)
565 {
566   int j, numargs;
567
568   macrodesc->name = gen_new_macro_name ();
569   numargs = xrandom (DEFAULT_MAX_MACRO_ARGS + 1);
570   --numargs;
571   if (numargs > 0)
572     {
573       macrodesc->args = (char **) xmalloc (numargs * sizeof(char *));
574       for (j = 0; j < numargs; ++j)
575         {
576           macrodesc->args[j] = gen_random_local_name (j, NULL);
577         }
578     }
579   macrodesc->numargs = numargs;
580   macrodesc->use = 1;
581 }
582
583 /* Generate a macro name.  */
584
585 char *
586 gen_new_macro_name (void)
587 {
588   return gen_unique_global_name ("M", (xrandom (3) > 0));
589 }
590
591 /* Create definitions of the desired number of enums.  */
592
593 void
594 create_enums (void)
595 {
596   int i;
597
598   printf ("Creating %d enums...\n", num_enums);
599   enums =
600     (struct enum_desc *) xmalloc (num_enums * sizeof(struct enum_desc));
601   for (i = 0; i < num_enums; ++i)
602     {
603       create_enum (&(enums[i]));
604     }
605   printf ("Creating %d lib_enums...\n", num_lib_enums);
606   lib_enums =
607     (struct enum_desc *) xmalloc (num_lib_enums * sizeof(struct enum_desc));
608   for (i = 0; i < num_lib_enums; ++i)
609     {
610       create_enum (&(lib_enums[i]));
611       if (!probability(lib_percent))
612         lib_enums[i].use = 0;
613     }
614 }
615
616 void
617 create_enum (struct enum_desc *enumdesc)
618 {
619   int j, num;
620
621   /* Let some enums be anonymous. */
622   if (xrandom (100) < 50)
623     enumdesc->name = gen_unique_global_name (NULL, 0);
624   num = num_enumerators / 2 + xrandom (num_enumerators);
625   if (num <= 0)
626     num = 1;
627   enumdesc->enumerators =
628     (struct enumerator_desc *) xmalloc (num * sizeof(struct enumerator_desc));
629   for (j = 0; j < num; ++j)
630     {
631       enumdesc->enumerators[j].name = gen_random_enumerator_name ();
632     }
633   enumdesc->num_enumerators = j;
634   enumdesc->use = 1;
635 }
636
637 /* Generate a unique enumerator within an enum.  */
638
639 char *
640 gen_random_enumerator_name (void)
641 {
642   return gen_unique_global_name ("enum", 0);
643 }
644
645 /* Create definitions of the desired number of structures.  */
646
647 void
648 create_structs (void)
649 {
650   int i;
651
652   printf ("Creating %d structs...\n", num_structs);
653   structs =
654     (struct struct_desc *) xmalloc (num_structs * sizeof(struct struct_desc));
655   for (i = 0; i < num_structs; ++i)
656     {
657       create_struct (&(structs[i]));
658     }
659   printf ("Creating %d library structs...\n", num_lib_structs);
660   lib_structs =
661     (struct struct_desc *) xmalloc (num_lib_structs * sizeof(struct struct_desc));
662   for (i = 0; i < num_lib_structs; ++i)
663     {
664       create_struct (&(lib_structs[i]));
665       if (!probability(lib_percent))
666         lib_structs[i].use = 0;
667     }
668 }
669
670 void
671 create_struct (struct struct_desc *structdesc)
672 {
673   int j, numf;
674
675   structdesc->name = gen_unique_global_name (NULL, 0);
676   numf = xrandom (num_fields) + 1;
677   structdesc->fields =
678     (struct field_desc *) xmalloc (numf * sizeof(struct field_desc));
679   for (j = 0; j < numf; ++j)
680     {
681       structdesc->fields[j].type = random_type ();
682       structdesc->fields[j].name = gen_random_field_name (j);
683     }
684   structdesc->numfields = numf;
685   structdesc->use = 1;
686 }
687
688 char *
689 gen_random_field_name (int n)
690 {
691   char namebuf[100];
692
693   /* (should have more variety) */
694   sprintf (namebuf, "field%d", n);
695   return copy_string (namebuf);
696 }
697
698 /* Create a number of functions with random numbers of arguments. */
699
700 /* (should gen with random arg types also) */
701
702 void
703 create_functions (void)
704 {
705   int i;
706
707   printf ("Creating %d functions...\n", num_functions);
708   functions =
709     (struct function_desc *) xmalloc (num_functions * sizeof(struct function_desc));
710   /* Generate the main program, as the first function.  */
711   functions[0].name = "main";
712   functions[0].numargs = 0;
713   /* Generate all the other functions.  The bodies don't get created
714      until the functions are being written out.  */
715   for (i = 1; i < num_functions; ++i)
716     {
717       create_function (&(functions[i]));
718     }
719
720   printf ("Creating %d library functions...\n", num_lib_functions);
721   lib_functions =
722     (struct function_desc *) xmalloc (num_lib_functions * sizeof(struct function_desc));
723   for (i = 0; i < num_lib_functions; ++i)
724     {
725       create_function (&(lib_functions[i]));
726       if (!probability(lib_percent))
727         lib_functions[i].use = 0;
728     }
729 }
730
731 /* Generate the details of a single function.  */
732
733 void
734 create_function (struct function_desc *fndesc)
735 {
736   int j, range, numargs;
737
738   fndesc->name = gen_unique_global_name ("fn", 0);
739   /* Choose the number of arguments, preferring shorter argument
740      lists by using a simple binomial distribution.  */
741   range = 2 * (max_function_args + 1);
742   numargs = 0;
743   for (j = 0; j < 6; ++j)
744     numargs += xrandom (range + 1);
745   if (j > 0)
746     numargs /= j;
747   /* Shift distribution so 0 is in the middle.  */
748   numargs -= max_function_args;
749   /* Fold negative values over to positive side.  */
750   if (numargs < 0)
751     numargs = -numargs;
752   if (numargs > max_function_args)
753     numargs = max_function_args;
754   fndesc->args =
755     (struct arg_desc *) xmalloc (numargs * sizeof(struct arg_desc));
756   for (j = 0; j < numargs; ++j)
757     {
758       fndesc->args[j].type = 0;
759       fndesc->args[j].name = gen_random_local_name (j, NULL);
760     }
761   fndesc->numargs = numargs;
762   fndesc->use = 1;
763 }
764
765 void
766 write_header_file (int n)
767 {
768   int i;
769   char tmpbuf[100];
770   FILE *fp;
771
772   sprintf (tmpbuf, "%s%d.h", file_base_name, n);
773   fp = fopen (tmpbuf, "w");
774   if (fp)
775     {
776       if (commenting > 0)
777         fprintf (fp, "/* header */\n");
778       if (1)
779         {
780           printf ("Writing %d macros...\n", num_macros);
781           for (i = 0; i < num_macros; ++i)
782             {
783               write_macro (fp, &(macros[i]));
784             }
785         }
786       if (1)
787         {
788           printf ("Writing %d enums...\n", num_enums);
789           printf ("  (Each enum contains up to %d values)\n", num_enumerators);
790           for (i = 0; i < num_enums; ++i)
791             {
792               write_enum (fp, &(enums[i]));
793             }
794         }
795       if (1)
796         {
797           printf ("Writing %d structs...\n", num_structs);
798           printf ("  (Each struct contains %d fields)\n", num_fields);
799           for (i = 0; i < num_structs; ++i)
800             {
801               write_struct (fp, &(structs[i]));
802             }
803         }
804       if (1)
805         {
806           printf ("Writing %d function decls...\n", num_functions);
807           for (i = 0; i < num_functions; ++i)
808             {
809               write_function_decl (fp, &(functions[i]));
810             }
811         }
812       fclose (fp);
813     }
814 }
815
816 void
817 write_lib_header_file (void)
818 {
819   int i;
820   char tmpbuf[100];
821   FILE *fp;
822
823   sprintf (tmpbuf, "%slib.h", file_base_name);
824   fp = fopen (tmpbuf, "w");
825   if (fp)
826     {
827       if (commenting > 0)
828         fprintf (fp, "/* library header */\n");
829       if (1)
830         {
831           printf ("Writing %d library macros...\n", num_lib_macros);
832           for (i = 0; i < num_lib_macros; ++i)
833             {
834               write_macro (fp, &(lib_macros[i]));
835             }
836         }
837       if (1)
838         {
839           printf ("Writing %d library enums...\n", num_lib_enums);
840           printf ("  (Each enum contains up to %d values)\n", num_enumerators);
841           for (i = 0; i < num_lib_enums; ++i)
842             {
843               write_enum (fp, &(lib_enums[i]));
844             }
845         }
846       if (1)
847         {
848           printf ("Writing %d library structs...\n", num_lib_structs);
849           printf ("  (Each struct contains %d fields)\n", num_fields);
850           for (i = 0; i < num_lib_structs; ++i)
851             {
852               write_struct (fp, &(lib_structs[i]));
853             }
854         }
855       if (1)
856         {
857           printf ("Writing %d lib function decls...\n", num_lib_functions);
858           for (i = 0; i < num_lib_functions; ++i)
859             {
860               write_function_decl (fp, &(lib_functions[i]));
861             }
862         }
863       fclose (fp);
864     }
865 }
866
867 void
868 write_macro (FILE *fp, struct macro_desc *macrodesc)
869 {
870   int i, j;
871
872   fprintf (fp, "#define %s", macrodesc->name);
873   /* Negative # arguments indicates an argumentless macro instead of
874      one with zero arguments. */
875   if (macrodesc->numargs >= 0)
876     {
877       fprintf (fp, "(");
878       for (j = 0; j < macrodesc->numargs; ++j)
879         {
880           if (j > 0)
881             fprintf (fp, ",");
882           fprintf (fp, "%s", macrodesc->args[j]);
883         }
884       fprintf (fp, ")");
885     }
886   /* Generate a macro body. */
887   switch (xrandom(2))
888     {
889     case 0:
890       fprintf (fp, " \\\n");
891       fprintf (fp, "(");
892       if (macrodesc->numargs > 0)
893         {
894           for (i = 0; i < macrodesc->numargs; ++i)
895             {
896               if (i > 0)
897                 fprintf (fp, ",");
898               fprintf (fp, " \\\n");
899               fprintf (fp, "  (%s)", macrodesc->args[i]);
900               if (xrandom (2) == 0)
901                 {
902                   fprintf (fp, ",");
903                   fprintf (fp, " \\\n");
904                   fprintf (fp, " ((int) (%s))", macrodesc->args[i]);
905                 }
906             }
907           fprintf (fp, " \\\n");
908         }
909       else
910         {
911           fprintf (fp, " (1)");
912         }
913       fprintf (fp, ")");
914       break;
915     default:
916       fprintf (fp, " (%d)", xrandom (100));
917       break;
918     }
919   fprintf (fp, "\n\n");
920 }
921
922 /* Write out the definition of a enum. */
923
924 void
925 write_enum (FILE *fp, struct enum_desc *enumdesc)
926 {
927   int j;
928
929   fprintf (fp, "enum");
930   if (enumdesc->name)
931     fprintf (fp, " %s", enumdesc->name);
932   fprintf (fp, " {");
933   for (j = 0; j < enumdesc->num_enumerators; ++j)
934     {
935       if (j > 0)
936         fprintf (fp, ",");
937       fprintf (fp, "\n  %s", enumdesc->enumerators[j].name);
938     }
939   fprintf (fp, "\n};\n\n");
940 }
941
942 /* Write out the definition of a structure. */
943
944 void
945 write_struct (FILE *fp, struct struct_desc *structdesc)
946 {
947   int j;
948
949   fprintf (fp, "struct %s {\n", structdesc->name);
950   for (j = 0; j < structdesc->numfields; ++j)
951     {
952       fprintf (fp, "  %s %s;\n",
953                name_from_type (structdesc->fields[j].type),
954                structdesc->fields[j].name);
955     }
956   fprintf (fp, "};\n\n");
957 }
958
959 void
960 write_function_decl (FILE *fp, struct function_desc *fndesc)
961 {
962   int i;
963
964   fprintf (fp, "int %s (", fndesc->name);
965   if (language != knr)
966     {
967       for (i = 0; i < fndesc->numargs; ++i)
968         {
969           fprintf (fp, "int %s", fndesc->args[i].name);
970           if (i + 1 < fndesc->numargs)
971             fprintf (fp, ", ");
972         }
973     }
974   fprintf (fp, ");\n");
975 }
976
977 /* Write a complete source file. */
978
979 void
980 write_source_file (int n)
981 {
982   char tmpbuf[100];
983   int j;
984   FILE *fp;
985   extern unsigned long initial_randstate;
986
987   sprintf (tmpbuf, "%s%d.%s",
988            file_base_name, n, extensions[language]);
989   fp = fopen (tmpbuf, "w");
990   if (fp)
991     {
992       fprintf (fp,
993                "/* A fine software product by SPU %s, random seed == %d */\n\n",
994                version_string, (int) initial_randstate);
995       if (1 /*num_lib_header_files*/ > 0)
996         {
997           for (j = 0; j < 1 /*num_header_files*/; ++j)
998             {
999               fprintf (fp, "#include \"%slib.h\"\n", file_base_name);
1000             }
1001           fprintf (fp, "\n");
1002         }
1003       if (num_header_files > 0)
1004         {
1005           for (j = 0; j < num_header_files; ++j)
1006             {
1007               fprintf (fp, "#include \"%s%d.h\"\n", file_base_name, j);
1008             }
1009           fprintf (fp, "\n");
1010         }
1011
1012       if (n == 0)
1013         printf ("  (Each file contains %d functions)\n",
1014                 num_functions_per_file);
1015
1016       for (j = 0; j < num_functions_per_file; ++j)
1017         {
1018           write_function (fp, n * num_functions_per_file + j);
1019         }
1020     }
1021   fclose (fp);
1022 }
1023
1024 void
1025 write_function (FILE *fp, int n)
1026 {
1027   int i, k;
1028
1029   fprintf(fp, "int\n%s (", functions[n].name);
1030   for (i = 0; i < functions[n].numargs; ++i)
1031     {
1032       if (language != knr)
1033         {
1034           fprintf (fp, "int ");
1035         }
1036       fprintf (fp, "%s", functions[n].args[i].name);
1037       if (i + 1 < functions[n].numargs)
1038         fprintf (fp, ", ");
1039     }
1040   fprintf(fp, ")\n");
1041   if (language == knr)
1042     {
1043       for (i = 0; i < functions[n].numargs; ++i)
1044         {
1045           fprintf (fp, "int %s;\n", functions[n].args[i].name);
1046         }
1047     }
1048   fprintf(fp, "{\n");
1049   /* Generate a plausible function body by writing a number of
1050      statements. */
1051   for (k = 0; k < function_length; ++k)
1052     {
1053       write_statement (fp, 1, function_depth - 1 + xrandom (3));
1054     }
1055   fprintf (fp, "}\n\n");
1056 }
1057
1058 void
1059 write_lib_source_file (void)
1060 {
1061   char tmpbuf[100];
1062   int j;
1063   FILE *fp;
1064
1065   sprintf (tmpbuf, "%slib.%s", file_base_name, extensions[language]);
1066   fp = fopen (tmpbuf, "w");
1067   if (fp)
1068     {
1069       if (1 /*num_lib_header_files*/ > 0)
1070         {
1071           for (j = 0; j < 1 /*num_header_files*/; ++j)
1072             {
1073               fprintf (fp, "#include \"%slib.h\"\n", file_base_name);
1074             }
1075           fprintf (fp, "\n");
1076         }
1077
1078       for (j = 0; j < num_lib_functions; ++j)
1079         {
1080           write_lib_function (fp, j);
1081         }
1082     }
1083   fclose (fp);
1084 }
1085
1086 /* Generate empty bodies for library function definitions.  */
1087
1088 void
1089 write_lib_function (FILE *fp, int n)
1090 {
1091   int i;
1092
1093   fprintf (fp, "int\n%s (", lib_functions[n].name);
1094   for (i = 0; i < lib_functions[n].numargs; ++i)
1095     {
1096       if (language != knr)
1097         {
1098           fprintf (fp, "int ");
1099         }
1100       fprintf (fp, "%s", lib_functions[n].args[i].name);
1101       if (i + 1 < lib_functions[n].numargs)
1102         fprintf (fp, ", ");
1103     }
1104   fprintf (fp, ")");
1105   if (!lib_functions[n].use)
1106     fprintf (fp, "/* unused */");
1107   fprintf (fp, "\n");
1108   if (language == knr)
1109     {
1110       for (i = 0; i < lib_functions[n].numargs; ++i)
1111         {
1112           fprintf (fp, "int %s;\n", lib_functions[n].args[i].name);
1113         }
1114     }
1115   fprintf (fp, "{\n");
1116   fprintf (fp, "}\n\n");
1117 }
1118
1119 void
1120 write_statement (FILE *fp, int depth, int max_depth)
1121 {
1122   int i;
1123
1124   for (i = 0; i < depth; ++i)
1125     fprintf (fp, "  ");
1126   /* Always do non-recursive statements if going too deep. */
1127   if (depth >= max_depth)
1128     {
1129       write_expression (fp, 0, xrandom(4) + 1);
1130       fprintf (fp, ";\n");
1131       return;
1132     }
1133   switch (xrandom(2))
1134     {
1135     case 0:
1136       write_expression (fp, 0, xrandom(4) + 1);
1137       fprintf (fp, ";");
1138       break;
1139     case 1:
1140       fprintf (fp, "if (");
1141       write_expression (fp, 0, xrandom(2) + 1);
1142       fprintf (fp, ") {\n");
1143       write_statement(fp, depth + 1, max_depth);
1144       for (i = 0; i < depth; ++i)
1145         fprintf (fp, "  ");
1146       fprintf (fp, "}");
1147       break;
1148     }
1149   fprintf(fp, "\n");
1150 }
1151
1152 /* Write a single expression. */
1153
1154 void
1155 write_expression (FILE *fp, int depth, int max_depth)
1156 {
1157   int n, n2, j;
1158
1159   /* Always do non-recursive statements if going too deep. */
1160   if (depth >= max_depth)
1161     {
1162     getout:
1163       switch (xrandom(10))
1164         {
1165         case 7:
1166           fprintf (fp, "%d", xrandom (1000));
1167           break;
1168         default:
1169           fprintf (fp, "%d", xrandom (127));
1170           break;
1171         }
1172       return;
1173     }
1174   switch (xrandom(10))
1175     {
1176     case 0:
1177       for (j = 0; j < 1000; ++j)
1178         {
1179           n = xrandom (num_lib_functions);
1180           if (lib_functions[n].use)
1181             break;
1182         }
1183       if (!lib_functions[n].use)
1184         goto getout;
1185       n = xrandom (num_lib_functions);
1186       fprintf(fp, "%s (", lib_functions[n].name);
1187       for (j = 0; j < lib_functions[n].numargs; ++j)
1188         {
1189           if (j > 0)
1190             fprintf (fp, ", ");
1191           write_expression(fp, depth + 1, max_depth - 1);
1192         }
1193       fprintf(fp, ")");
1194       break;
1195     case 7:
1196       n = xrandom (num_functions);
1197       fprintf(fp, "%s (", functions[n].name);
1198       for (j = 0; j < functions[n].numargs; ++j)
1199         {
1200           if (j > 0)
1201             fprintf (fp, ", ");
1202           write_expression(fp, depth + 1, max_depth - 1);
1203         }
1204       fprintf(fp, ")");
1205       break;
1206     case 1:
1207     case 6:
1208       for (j = 0; j < 1000; ++j)
1209         {
1210           n = xrandom (num_lib_macros);
1211           if (lib_macros[n].use)
1212             break;
1213         }
1214       if (!lib_macros[n].use)
1215         goto getout;
1216       fprintf(fp, "%s", lib_macros[n].name);
1217       if (lib_macros[n].numargs >= 0)
1218         {
1219           fprintf(fp, " (");
1220           for (j = 0; j < lib_macros[n].numargs; ++j)
1221             {
1222               if (j > 0)
1223                 fprintf (fp, ", ");
1224               write_expression(fp, depth + 1, max_depth - 1);
1225             }
1226           fprintf(fp, ")");
1227         }
1228       break;
1229     case 8:
1230       n = xrandom (num_macros);
1231       fprintf(fp, "%s", macros[n].name);
1232       if (macros[n].numargs >= 0)
1233         {
1234           fprintf(fp, " (");
1235           for (j = 0; j < macros[n].numargs; ++j)
1236             {
1237               if (j > 0)
1238                 fprintf (fp, ", ");
1239               write_expression(fp, depth + 1, max_depth - 1);
1240             }
1241           fprintf(fp, ")");
1242         }
1243       break;
1244     case 2:
1245       write_expression (fp, depth + 1, max_depth);
1246       fprintf (fp, " + ");
1247       write_expression (fp, depth + 1, max_depth);
1248       break;
1249     case 3:
1250       write_expression (fp, depth + 1, max_depth);
1251       fprintf (fp, " - ");
1252       write_expression (fp, depth + 1, max_depth);
1253       break;
1254     case 4:
1255       write_expression (fp, depth + 1, max_depth);
1256       fprintf (fp, " * ");
1257       write_expression (fp, depth + 1, max_depth);
1258       break;
1259     case 5:
1260       n = xrandom (num_enums);
1261       n2 = xrandom (enums[n].num_enumerators);
1262       fprintf (fp, "%s", enums[n].enumerators[n2].name);
1263       break;
1264     default:
1265       fprintf (fp, "%d", xrandom (127));
1266       break;
1267     }
1268 }
1269
1270 /* Write out a makefile that will compile the program just generated. */
1271
1272 void
1273 write_makefile (void)
1274 {
1275   char tmpbuf[100];
1276   int i, j;
1277   FILE *fp;
1278
1279   sprintf (tmpbuf, "%s.mk", file_base_name);
1280   fp = fopen (tmpbuf, "w");
1281   if (fp)
1282     {
1283       /* Name the compiler so we can change it easily.  */
1284       fprintf (fp, "CC = cc\n\n");
1285       /* Write dependencies and action line for the executable.  */
1286       fprintf (fp, "%s: ", file_base_name);
1287       for (i = 0; i < num_files; ++i)
1288         fprintf (fp, " %s%d.o", file_base_name, i);
1289       fprintf (fp, " %slib.o", file_base_name);
1290       fprintf (fp, "\n");
1291       fprintf (fp, "\t$(CC) -o %s.out", file_base_name);
1292       for (i = 0; i < num_files; ++i)
1293         fprintf (fp, " %s%d.o", file_base_name, i);
1294       fprintf (fp, " %slib.o", file_base_name);
1295       fprintf (fp, "\n\n");
1296       /* Write dependencies for individual files. */
1297       for (i = 0; i < num_files; ++i)
1298         {
1299           fprintf (fp, " %s%d.o:        %s%d.%s",
1300                    file_base_name, i, file_base_name, i,
1301                    extensions[language]);
1302           for (j = 0; j < num_header_files; ++j)
1303             fprintf (fp, " %s%d.h", file_base_name, j);
1304           fprintf (fp, "\n");
1305           fprintf (fp, "\t$(CC) -c %s%d.%s\n",
1306                    file_base_name, i, extensions[language]);
1307         }
1308       fprintf (fp, " %slib.o:   %slib.%s %slib.h",
1309                file_base_name, file_base_name, extensions[language],
1310                file_base_name);
1311       fprintf (fp, "\n");
1312       fprintf (fp, "\t$(CC) -c %slib.%s\n",
1313                file_base_name, extensions[language]);
1314       fclose (fp);
1315     }
1316 }
1317
1318
1319 /* Utility/general functions. */
1320
1321 char *
1322 gen_unique_global_name (char *root, int upcase)
1323 {
1324   int i, j;
1325   char *str, namebuf[100];
1326
1327   if (global_hash_table == NULL)
1328     {
1329       global_hash_table =
1330         (struct hash_table *) xmalloc (sizeof (struct hash_table));
1331     }
1332   str = NULL;
1333   /* Keep trying until we get a unique name. */
1334   for (i = 0; i < 100; ++i)
1335     {
1336       gen_random_global_name (root, namebuf);
1337       if (upcase)
1338         {
1339           for (j = 0; namebuf[j] != '\0'; ++j)
1340             namebuf[j] = toupper (namebuf[j]);
1341         }
1342       if (get_from_hash_table (namebuf, global_hash_table) == NULL)
1343         {
1344           str = add_to_hash_table (namebuf, global_hash_table);
1345           break;
1346         }
1347     }
1348   if (str == NULL)
1349     {
1350       fprintf (stderr, "Can't get a unique name!\n");
1351       exit(1);
1352     }
1353   return str;
1354 }
1355
1356 void
1357 gen_random_global_name (char *root, char *namebuf)
1358 {
1359   char smallbuf[100];
1360   int n, i, len;
1361
1362   namebuf[0] = '\0';
1363   switch (xrandom (4))
1364     {
1365     case 0:
1366       namebuf[0] = 'a' + xrandom (26);
1367       namebuf[1] = '\0';
1368       break;
1369     case 1:
1370       /* Convert a random number into a string, maybe with some
1371          underscores thrown in for flavor.  */
1372       n = xrandom (10000);
1373       i = 0;
1374       while (n > 0)
1375         {
1376           if (xrandom(6) == 0)
1377             namebuf[i++] = '_';
1378           namebuf[i++] = 'a' + (n % 26);
1379           n /= 26;
1380         }
1381       namebuf[i] = '\0';
1382       break;
1383     default:
1384       strcat (namebuf, random_computer_word ());
1385       break;
1386     }
1387   if (root != NULL)
1388     {
1389       strcat (namebuf, "_");
1390       strcat (namebuf, root);
1391     }
1392   switch (xrandom (4))
1393     {
1394     case 0:
1395       strcat (namebuf, "_");
1396       len = strlen (namebuf);
1397       namebuf[len] = 'a' + xrandom (26);
1398       namebuf[len + 1] = '\0';
1399       break;
1400     case 1:
1401       strcat (namebuf, "_");
1402       sprintf (smallbuf, "%d", xrandom (10000));
1403       strcat (namebuf, smallbuf);
1404       break;
1405     default:
1406       strcat (namebuf, "_");
1407       strcat (namebuf, random_computer_word ());
1408       break;
1409     }
1410 }
1411
1412 /* Generate a local variable name. */
1413
1414 char *
1415 gen_random_local_name (int numothers, char **others)
1416 {
1417   char namebuf[100];
1418
1419   sprintf (namebuf, "%s%d",
1420            (xrandom (2) == 0 ? random_computer_word () : "arg"),
1421            numothers + 1);
1422   return copy_string (namebuf);
1423 }
1424
1425 /* Generic hash table code. */
1426
1427 int
1428 hash_string (char *str)
1429 {
1430   int i, rslt;
1431
1432   rslt = 0;
1433   for (i = 0; str[i] != '\0'; ++i)
1434     {
1435       rslt ^= str[i];
1436       rslt %= 253;
1437     }
1438   return rslt;
1439 }
1440
1441 struct hash_entry *
1442 get_hash_entry (void)
1443 {
1444   return (struct hash_entry *) xmalloc (sizeof (struct hash_entry));
1445 }
1446
1447 char *
1448 add_to_hash_table (char *buf, struct hash_table *table)
1449 {
1450   int hash;
1451   struct hash_entry *ent, *lastent;
1452
1453   if (buf == NULL)
1454     buf = "";
1455   ++(table->numadds);
1456   hash = hash_string (buf);
1457   if (table->entries[hash] == NULL)
1458     {
1459       table->entries[hash] = get_hash_entry ();
1460       table->entries[hash]->val = copy_string (buf);
1461       return table->entries[hash]->val;
1462     }
1463   else
1464     {
1465       for (ent = table->entries[hash]; ent != NULL; ent = ent->next)
1466         {
1467           if (ent->val == NULL)
1468             return "null!?!";
1469           if (strcmp (buf, ent->val) == 0)
1470             return ent->val;
1471           lastent = ent;
1472         }
1473       if (lastent != NULL)
1474         {
1475           lastent->next = get_hash_entry ();
1476           lastent->next->val = copy_string (buf);
1477           return lastent->next->val;
1478         }
1479     }
1480   /* should never happen */
1481   return "?!hash!?";
1482 }
1483
1484 char *
1485 get_from_hash_table (char *buf, struct hash_table *table)
1486 {
1487   int hash;
1488   struct hash_entry *ent, *lastent;
1489
1490   if (buf == NULL)
1491     buf = "";
1492   hash = hash_string (buf);
1493   if (table->entries[hash] == NULL)
1494     {
1495       return NULL;
1496     }
1497   else
1498     {
1499       for (ent = table->entries[hash]; ent != NULL; ent = ent->next)
1500         {
1501           if (ent->val == NULL)
1502             return "null!?!";
1503           if (strcmp (buf, ent->val) == 0)
1504             return ent->val;
1505           lastent = ent;
1506         }
1507       if (lastent != NULL)
1508         {
1509           return NULL;
1510         }
1511     }
1512   /* should never happen */
1513   return "?!hash!?";
1514 }
1515
1516 #include <time.h>
1517
1518 /* Random number handling is important but terrible/nonexistent in
1519    some systems.  Do it ourselves.  Also, this will give repeatable
1520    results across multiple platforms, which is important if this is
1521    being used to generate test cases. */
1522
1523 /* The random state *must* be at least 32 bits.  */
1524
1525 unsigned long initial_randstate = 0;
1526
1527 unsigned long randstate = 0;
1528
1529 /* Seed can come from elsewhere, for repeatability.  Otherwise, it comes
1530    from the current time, scaled down to where 32-bit arithmetic won't
1531    overflow.  */
1532
1533 void
1534 init_xrandom (int seed)
1535 {
1536   time_t tm;
1537         
1538   if (seed > 0)
1539     {
1540       /* If the random state is already set, changes are somewhat
1541          suspicious.  */
1542       if (randstate > 0)
1543         {
1544           fprintf (stderr, "Randstate being changed from %lu to %d\n",
1545                    randstate, seed);
1546         }
1547       randstate = seed;
1548     }
1549   else
1550     {
1551       time (&tm);
1552       randstate = tm;
1553     }
1554   /* Whatever its source, put the randstate into known range (0 - 99999).  */
1555   randstate = abs (randstate);
1556   randstate %= 100000L;
1557   /* This is kept around for the sake of error reporting. */
1558   initial_randstate = randstate;
1559 }
1560
1561 /* Numbers lifted from Numerical Recipes, p. 198.  */
1562 /* Arithmetic must be 32-bit.  */
1563
1564 int
1565 xrandom (int m)
1566 {
1567   randstate = (8121 * randstate + 28411) % 134456L;
1568   return ((m * randstate) / 134456L);
1569 }
1570
1571 /* Percentage probability, with bounds checking. */
1572
1573 int
1574 probability(int prob)
1575 {
1576   if (prob <= 0)
1577     return 0;
1578   if (prob >= 100)
1579     return 1;
1580   return (xrandom(100) < prob);
1581 }
1582
1583 char *
1584 xmalloc (int amt)
1585 {
1586   char *value = (char *) malloc (amt);
1587
1588   if (value == NULL)
1589     {
1590       /* This is pretty serious, have to get out quickly.  */
1591       fprintf (stderr, "Memory exhausted!!\n");
1592       exit (1);
1593     }
1594   /* Save callers from having to clear things themselves.  */
1595   memset (value, 0, amt);
1596   return value;
1597 }
1598
1599 /* Copy a string to newly-allocated space.  The new space is never
1600    freed.  */
1601
1602 char *
1603 copy_string (char *str)
1604 {
1605   int len = strlen (str);
1606   char *rslt;
1607   
1608   rslt = xmalloc (len + 1);
1609   strcpy (rslt, str);
1610   return rslt;
1611 }