OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [utils/] [spu/] [spu.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* 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
#include <time.h>
28
 
29
char *version_string = "0.5";
30
 
31
/* These values are the builtin defaults, mainly useful for testing
32
   purposes, or if the user is uninterested in setting a value.  */
33
 
34
#define DEFAULT_NUM_FILES 5
35
 
36
#define DEFAULT_NUM_HEADER_FILES 1
37
 
38
#define DEFAULT_NUM_MACROS 10
39
 
40
#define DEFAULT_NUM_LIB_MACROS 30
41
 
42
#define DEFAULT_MAX_MACRO_ARGS 5
43
 
44
#define DEFAULT_NUM_ENUMS 10
45
 
46
#define DEFAULT_NUM_LIB_ENUMS 30
47
 
48
#define DEFAULT_NUM_ENUMERATORS 10
49
 
50
#define DEFAULT_NUM_STRUCTS 10
51
 
52
#define DEFAULT_NUM_LIB_STRUCTS 30
53
 
54
#define DEFAULT_NUM_FIELDS 20
55
 
56
#define DEFAULT_NUM_CLASSES 10
57
 
58
#define DEFAULT_NUM_LIB_CLASSES 30
59
 
60
#define DEFAULT_NUM_METHODS 20
61
 
62
#define DEFAULT_NUM_FUNCTIONS 100
63
 
64
#define DEFAULT_NUM_LIB_FUNCTIONS 300
65
 
66
#define DEFAULT_MAX_FUNCTION_ARGS 8
67
 
68
#define DEFAULT_FUNCTION_LENGTH 20
69
 
70
#define DEFAULT_FUNCTION_DEPTH 3
71
 
72
#define DEFAULT_LIB_PERCENT 10
73
 
74
/* Generic hash table.  */
75
 
76
struct hash_entry
77
{
78
  char *val;
79
  struct hash_entry *next;
80
};
81
 
82
struct hash_table
83
{
84
  struct hash_entry *entries[253];
85
  int numadds;
86
};
87
 
88
enum decl_types {
89
  d_nothing,
90
  d_macro,
91
  d_enum,
92
  d_struct,
93
  d_class,
94
  d_function
95
};
96
 
97
enum {
98
  t_nothing = 0,
99
  t_void = 1,
100
  t_int = 2,
101
  t_short = 3,
102
  t_char = 4,
103
  t_first_user = 100,
104
  t_char_ptr = 1000004
105
};
106
 
107
char *typenames[] = { "?", "void", "int", "short", "char" };
108
 
109
struct macro_desc
110
{
111
  int id;
112
  char *name;
113
  int numargs;
114
  char **args;
115
  int use;
116
};
117
 
118
struct enumerator_desc
119
{
120
  char *name;
121
};
122
 
123
struct enum_desc
124
{
125
  int id;
126
  char *name;
127
  int num_enumerators;
128
  struct enumerator_desc *enumerators;
129
  int use;
130
};
131
 
132
struct field_desc
133
{
134
  int type;
135
  char *name;
136
};
137
 
138
struct struct_desc
139
{
140
  int id;
141
  char *name;
142
  int numfields;
143
  struct field_desc *fields;
144
  int use;
145
};
146
 
147
/* (should add unions as type of struct) */
148
 
149
struct class_desc
150
{
151
  int id;
152
  char *name;
153
  int numfields;
154
  struct field_desc *fields;
155
  int nummethods;
156
  struct function_desc *methods;
157
  int use;
158
};
159
 
160
struct type_desc
161
{
162
  char *name;
163
};
164
 
165
struct arg_desc
166
{
167
  int type;
168
  char *name;
169
};
170
 
171
struct function_desc
172
{
173
  int id;
174
  char *name;
175
  int return_type;
176
  int numargs;
177
  struct arg_desc *args;
178
  struct class_desc *class;
179
  int use;
180
};
181
 
182
struct file_desc
183
{
184
  char *name;
185
};
186
 
187
struct decl_entry {
188
  enum decl_types type;
189
  union {
190
    struct macro_desc *macro_d;
191
    struct enum_desc *enum_d;
192
    struct struct_desc *struct_d;
193
    struct class_desc *class_d;
194
    struct function_desc *function_d;
195
  } decl;
196
  int seq;
197
  int order;
198
};
199
 
200
struct decl_table {
201
  int size;
202
  int nextentry;
203
  struct decl_entry *entries;
204
};
205
 
206
/* Function declarations.  */
207
 
208
void display_usage (void);
209
 
210
int hash_string (char *str);
211
 
212
struct hash_entry *get_hash_entry (void);
213
 
214
char *add_to_hash_table (char *buf, struct hash_table *table);
215
 
216
char *get_from_hash_table (char *buf, struct hash_table *table);
217
 
218
void init_xrandom (int seed);
219
 
220
int xrandom (int n);
221
 
222
int probability (int prob);
223
 
224
char *copy_string (char *str);
225
 
226
char *xmalloc (int n);
227
 
228
char *gen_unique_global_name (char *root, int upcase);
229
 
230
void gen_random_global_name (char *root, char *namebuf);
231
 
232
char *gen_random_local_name (int n, char **others);
233
 
234
void create_macros (void);
235
 
236
void create_macro (struct macro_desc *macrodesc);
237
 
238
char *gen_new_macro_name (void);
239
 
240
void create_enums (void);
241
 
242
void create_enum (struct enum_desc *enumdesc);
243
 
244
char *gen_random_enumerator_name (void);
245
 
246
void create_structs (void);
247
 
248
void create_struct (struct struct_desc *structdesc, int lib);
249
 
250
char *gen_random_field_name (int n);
251
 
252
void create_classes (void);
253
 
254
void create_class (struct class_desc *classdesc, int lib);
255
 
256
void create_functions (void);
257
 
258
void create_function (struct function_desc *fndesc, int lib);
259
 
260
void write_header_file (int n);
261
 
262
void write_lib_header_file (void);
263
 
264
void write_source_file (int n);
265
 
266
void write_lib_source_file (void);
267
 
268
void write_macro (FILE *fp, struct macro_desc *macrodesc);
269
 
270
void write_enum (FILE *fp, struct enum_desc *enumdesc);
271
 
272
void write_struct (FILE *fp, struct struct_desc *structdesc);
273
 
274
void write_class (FILE *fp, struct class_desc *classdesc);
275
 
276
void write_function_decl (FILE *fp, struct function_desc *fndesc);
277
 
278
void write_function (FILE *fp, struct function_desc *fndesc);
279
 
280
void write_lib_function (FILE *fp, int n);
281
 
282
void write_statement (FILE *fp, int depth, int max_depth);
283
 
284
void write_expression (FILE *fp, int rslttype, int depth, int max_depth,
285
                       int exclude_id);
286
 
287
void write_description_block (FILE *fp);
288
 
289
void write_makefile (void);
290
 
291
/* Global variables.  */
292
 
293
/* The possible languages. */
294
 
295
enum languages { knr, c, cpp, objc };
296
 
297
enum languages language = c;
298
 
299
/* Filename extensions to use with each language type.  */
300
 
301
char *extensions[] = { "c", "c", "cc", "m" };
302
 
303
/* Names for each language.  */
304
 
305
char *lang_names[] = { "K&R C", "standard C", "standard C++", "Objective-C" };
306
 
307
int num_files = DEFAULT_NUM_FILES;
308
 
309
int num_header_files = DEFAULT_NUM_HEADER_FILES;
310
 
311
char *file_base_name = "file";
312
 
313
int num_macros = DEFAULT_NUM_MACROS;
314
 
315
int num_lib_macros = DEFAULT_NUM_LIB_MACROS;
316
 
317
int num_enums = DEFAULT_NUM_ENUMS;
318
 
319
int num_lib_enums = DEFAULT_NUM_LIB_ENUMS;
320
 
321
int num_enumerators = DEFAULT_NUM_ENUMERATORS;
322
 
323
int num_structs = DEFAULT_NUM_STRUCTS;
324
 
325
int num_lib_structs = DEFAULT_NUM_LIB_STRUCTS;
326
 
327
int num_fields = DEFAULT_NUM_FIELDS;
328
 
329
int num_classes = DEFAULT_NUM_CLASSES;
330
 
331
int num_lib_classes = DEFAULT_NUM_LIB_CLASSES;
332
 
333
int num_methods = DEFAULT_NUM_METHODS;
334
 
335
int num_functions = DEFAULT_NUM_FUNCTIONS;
336
 
337
int num_lib_functions = DEFAULT_NUM_LIB_FUNCTIONS;
338
 
339
int max_function_args = DEFAULT_MAX_FUNCTION_ARGS;
340
 
341
int function_length = DEFAULT_FUNCTION_LENGTH;
342
 
343
int function_depth = DEFAULT_FUNCTION_DEPTH;
344
 
345
/* Percentage of library constructs that will be referenced.  */
346
 
347
int lib_percent = DEFAULT_LIB_PERCENT;
348
 
349
int randomize_order = 1;
350
 
351
int num_functions_per_file;
352
 
353
/* The amount of commenting in the source.  */
354
 
355
int commenting = 0;
356
 
357
/* Hash table for globally visible symbols.  */
358
 
359
struct hash_table *global_hash_table;
360
 
361
/* The seed for the random number generator.  */
362
 
363
int seed = -1;
364
 
365
int next_id = 1;
366
 
367
/* Space to record info about generated constructs.  */
368
 
369
struct macro_desc *macros;
370
 
371
struct macro_desc *lib_macros;
372
 
373
struct enum_desc *enums;
374
 
375
struct enum_desc *lib_enums;
376
 
377
struct struct_desc *structs;
378
 
379
struct struct_desc *lib_structs;
380
 
381
struct class_desc *classes;
382
 
383
struct class_desc *lib_classes;
384
 
385
struct function_desc *functions;
386
 
387
struct function_desc *lib_functions;
388
 
389
struct decl_table order;
390
 
391
struct decl_table lib_order;
392
 
393
int num_computer_terms;
394
 
395
/* Likely words to appear in names of things.  These must never be
396
   valid C/C++ keywords, since they may appear by themselves in some
397
   contexts.  */
398
 
399
char *computerese[] = {
400
  "add", "all", "alloc", "allocate", "area", "array", "at",
401
  "bogus", "buf", "buff", "buffer", "by", "btree",
402
  "ch", "chr", "clean", "cleanup", "count", "create", "cull",
403
  "data", "del", "delete_", "depth", "desc", "dest", "discard", "dismiss",
404
  "dma", "done", "dst",
405
  "fill", "find", "fn", "for_",
406
  "gc", "go", "goto_", "grok", "gronk", "group", "grovel",
407
  "hack", "hacked", "have", "heap",
408
  "in", "ind", "index", "ini", "init", "initial", "inside",
409
  "lab", "label", "last", "len", "length", "line", "lis", "list", "lose",
410
  "make", "mark", "mod", "modify", "more",
411
  "name", "nest", "nesting", "new_", "next", "node", "null", "num", "number",
412
  "part", "partial",
413
  "query", "queue",
414
  "ob", "obj", "object", "of",
415
  "pc", "pnt", "point", "pop", "pos", "position", "push",
416
  "raw", "recalc", "rect", "rectangle", "rel", "relative", "ret", "rslt",
417
  "remove", "reset", "rmv",
418
  "see", "set", "shape", "stack", "str", "string",
419
  "tab", "table", "tbl", "tag", "tree",
420
  "undel", "undo", "unmark", "use",
421
  "vary", "vec", "vect", "vector", "virt", "virtual_",
422
  "win", "wind", "window", "word",
423
  "zbuf",
424
  NULL
425
};
426
 
427
/* Return a word that commonly appears in programs. */
428
 
429
char *
430
random_computer_word (void)
431
{
432
  if (num_computer_terms == 0)
433
    {
434
      int i;
435
 
436
      for (i = 0; computerese[i] != NULL; ++i)
437
        ;
438
      num_computer_terms = i;
439
    }
440
  return computerese[xrandom (num_computer_terms)];
441
}
442
 
443
int
444
main (int argc, char **argv)
445
{
446
  int i, num;
447
  char *arg;
448
 
449
 
450
  /* Parse all the arguments. */
451
  /* (should check on numeric values) */
452
  for (i = 1; i < argc; ++i)
453
    {
454
      arg = argv[i];
455
      if (strcmp(arg, "--basename") == 0)
456
        {
457
          file_base_name = copy_string(argv[++i]);
458
        }
459
      else if (strcmp(arg, "--classes") == 0)
460
        {
461
          num = strtol (argv[++i], NULL, 10);
462
          num_classes = num;
463
        }
464
      else if (strcmp(arg, "--comments") == 0)
465
        {
466
          num = strtol (argv[++i], NULL, 10);
467
          commenting = num;
468
        }
469
      else if (strcmp(arg, "--enums") == 0)
470
        {
471
          num = strtol (argv[++i], NULL, 10);
472
          num_enums = num;
473
        }
474
      else if (strcmp(arg, "--enumerators") == 0)
475
        {
476
          num = strtol (argv[++i], NULL, 10);
477
          num_enumerators = num;
478
        }
479
      else if (strcmp(arg, "--fields") == 0)
480
        {
481
          num = strtol (argv[++i], NULL, 10);
482
          num_fields = num;
483
        }
484
      else if (strcmp(arg, "--files") == 0)
485
        {
486
          num = strtol (argv[++i], NULL, 10);
487
          num_files = num;
488
        }
489
      else if (strcmp(arg, "--functions") == 0)
490
        {
491
          num = strtol (argv[++i], NULL, 10);
492
          num_functions = num;
493
        }
494
      else if (strcmp(arg, "--function-length") == 0)
495
        {
496
          num = strtol (argv[++i], NULL, 10);
497
          function_length = num;
498
        }
499
      else if (strcmp(arg, "--function-depth") == 0)
500
        {
501
          num = strtol (argv[++i], NULL, 10);
502
          function_depth = num;
503
        }
504
      else if (strcmp(arg, "--header-files") == 0)
505
        {
506
          num = strtol (argv[++i], NULL, 10);
507
          num_header_files = num;
508
        }
509
      else if (strcmp(arg, "--help") == 0)
510
        {
511
          display_usage ();
512
          exit (0);
513
        }
514
      else if (strcmp(arg, "--language") == 0)
515
        {
516
          if (strcmp (argv[i+1], "c") == 0)
517
            language = c;
518
          else if (strcmp (argv[i+1], "c++") == 0)
519
            language = cpp;
520
          else if (strcmp (argv[i+1], "knr") == 0)
521
            language = knr;
522
          else if (strcmp (argv[i+1], "objc") == 0)
523
            language = objc;
524
          ++i;
525
        }
526
      else if (strcmp(arg, "--lib-classes") == 0)
527
        {
528
          num = strtol (argv[++i], NULL, 10);
529
          num_lib_classes = num;
530
        }
531
      else if (strcmp(arg, "--lib-enums") == 0)
532
        {
533
          num = strtol (argv[++i], NULL, 10);
534
          num_lib_enums = num;
535
        }
536
      else if (strcmp(arg, "--lib-functions") == 0)
537
        {
538
          num = strtol (argv[++i], NULL, 10);
539
          num_lib_functions = num;
540
        }
541
      else if (strcmp(arg, "--lib-macros") == 0)
542
        {
543
          num = strtol (argv[++i], NULL, 10);
544
          num_lib_macros = num;
545
        }
546
      else if (strcmp(arg, "--lib-structs") == 0)
547
        {
548
          num = strtol (argv[++i], NULL, 10);
549
          num_lib_structs = num;
550
        }
551
      else if (strcmp(arg, "--macros") == 0)
552
        {
553
          num = strtol (argv[++i], NULL, 10);
554
          num_macros = num;
555
        }
556
      else if (strcmp(arg, "--methods") == 0)
557
        {
558
          num = strtol (argv[++i], NULL, 10);
559
          num_methods = num;
560
        }
561
      else if (strcmp(arg, "--seed") == 0)
562
        {
563
          num = strtol (argv[++i], NULL, 10);
564
          seed = num;
565
        }
566
      else if (strcmp(arg, "--structs") == 0)
567
        {
568
          num = strtol (argv[++i], NULL, 10);
569
          num_structs = num;
570
        }
571
      else if (strcmp(arg, "--version") == 0)
572
        {
573
          fprintf (stderr, "SPU program generator version %s\n",
574
                   version_string);
575
          exit (0);
576
        }
577
      else
578
        {
579
          fprintf (stderr, "Usage: \"%s\" not valid, ignored\n", arg);
580
          display_usage ();
581
        }
582
    }
583
  if (language != cpp)
584
    num_classes = num_lib_classes = 0;
585
  init_xrandom (seed);
586
  /* Round up the number of functions so each file gets the same
587
     number. */
588
  num_functions_per_file = (num_functions + num_files - 1) / num_files;
589
  num_functions = num_functions_per_file * num_files;
590
  /* Create the definitions of objects internally. */
591
  order.size =
592
    num_macros + num_enums + num_structs + num_classes + num_functions;
593
  order.nextentry = 0;
594
  order.entries =
595
    (struct decl_entry *) xmalloc (order.size * sizeof(struct decl_entry));
596
  lib_order.size = num_lib_macros + num_lib_enums + num_lib_structs + num_lib_classes + num_lib_functions;
597
  lib_order.nextentry = 0;
598
  lib_order.entries =
599
    (struct decl_entry *) xmalloc (lib_order.size * sizeof(struct decl_entry));
600
  create_macros ();
601
  create_enums ();
602
  create_structs ();
603
  create_functions ();
604
  create_classes ();
605
  /* Write out a bunch of files. */
606
  printf ("Writing %d header files...\n", num_header_files);
607
  for (i = 0; i < num_header_files; ++i)
608
    write_header_file (i);
609
  write_lib_header_file ();
610
  write_lib_source_file ();
611
  printf ("Writing %d files...\n", num_files);
612
  for (i = 0; i < num_files; ++i)
613
    write_source_file (i);
614
  /* Write out a makefile. */
615
  write_makefile ();
616
  /* Succeed if we actually wrote out a whole program correctly. */
617
  exit (0);
618
}
619
 
620
void
621
display_usage (void)
622
{
623
  fprintf (stderr, "Usage: spu [ ... options ... ]\n");
624
  fprintf (stderr, "\t--basename str (default \"%s\")\n", "file");
625
  fprintf (stderr, "\t--classes n (default %d)\n", DEFAULT_NUM_CLASSES);
626
  fprintf (stderr, "\t--comments n\n");
627
  fprintf (stderr, "\t--enums n (default %d)\n", DEFAULT_NUM_ENUMS);
628
  fprintf (stderr, "\t--enumerators n (default %d)\n", DEFAULT_NUM_ENUMERATORS);
629
  fprintf (stderr, "\t--fields n (default %d)\n", DEFAULT_NUM_FIELDS);
630
  fprintf (stderr, "\t--files n (default %d)\n", DEFAULT_NUM_FILES);
631
  fprintf (stderr, "\t--functions n (default %d)\n", DEFAULT_NUM_FUNCTIONS);
632
  fprintf (stderr, "\t--function-length n (default %d)\n", DEFAULT_FUNCTION_LENGTH);
633
  fprintf (stderr, "\t--function-depth n (default %d)\n", DEFAULT_FUNCTION_DEPTH);
634
  fprintf (stderr, "\t--header-files n (default %d)\n", DEFAULT_NUM_HEADER_FILES);
635
  fprintf (stderr, "\t--help\n");
636
  fprintf (stderr, "\t--language c|cpp|knr|objc (default c)\n");
637
  fprintf (stderr, "\t--lib-classes n (default %d)\n", DEFAULT_NUM_LIB_CLASSES);
638
  fprintf (stderr, "\t--lib-enums n (default %d)\n", DEFAULT_NUM_LIB_ENUMS);
639
  fprintf (stderr, "\t--lib-functions n (default %d)\n", DEFAULT_NUM_LIB_FUNCTIONS);
640
  fprintf (stderr, "\t--lib-macros n (default %d)\n", DEFAULT_NUM_LIB_MACROS);
641
  fprintf (stderr, "\t--lib-structs n (default %d)\n", DEFAULT_NUM_LIB_STRUCTS);
642
  fprintf (stderr, "\t--macros n (default %d)\n", DEFAULT_NUM_MACROS);
643
  fprintf (stderr, "\t--methods n (default %d)\n", DEFAULT_NUM_METHODS);
644
  fprintf (stderr, "\t--seed n\n");
645
  fprintf (stderr, "\t--structs n (default %d)\n", DEFAULT_NUM_STRUCTS);
646
  fprintf (stderr, "\t--version\n");
647
}
648
 
649
int
650
random_type (int libonly)
651
{
652
  int i, n;
653
 
654
  switch (xrandom (6))
655
    {
656
    case 0:
657
      return t_short;
658
    case 1:
659
      return t_char;
660
    case 2:
661
      return t_char_ptr;
662
    case 3:
663
      for (i = 0; i < 1000; ++i)
664
        {
665
          n = xrandom (num_lib_structs);
666
          if (lib_structs[n].id > 0 && lib_structs[n].use)
667
            return t_first_user + lib_structs[n].id;
668
        }
669
      return t_int;
670
    case 4:
671
      if (libonly)
672
        return t_int;
673
      for (i = 0; i < 1000; ++i)
674
        {
675
          n = xrandom (num_structs);
676
          if (structs[n].id > 0)
677
            return t_first_user + structs[n].id;
678
        }
679
      return t_int;
680
    default:
681
      return t_int;
682
    }
683
}
684
 
685
/* Given a numbered type, return its name.  */
686
 
687
char *
688
name_from_type (int n)
689
{
690
  int i;
691
  char tmpbuf[100];
692
 
693
  if (n < t_first_user)
694
    {
695
      return typenames[n];
696
    }
697
  else if (n >= 1000000 && (n - 1000000) < t_first_user)
698
    {
699
      sprintf (tmpbuf, "%s *", typenames[n - 1000000]);
700
      return copy_string (tmpbuf);
701
    }
702
  else
703
    {
704
      for (i = 0; i < num_structs; ++i)
705
        {
706
          if (structs[i].id == (n - t_first_user))
707
            {
708
              sprintf (tmpbuf, "struct %s *", structs[i].name);
709
              return copy_string (tmpbuf);
710
            }
711
        }
712
      for (i = 0; i < num_lib_structs; ++i)
713
        {
714
          if (lib_structs[i].id == (n - t_first_user))
715
            {
716
              sprintf (tmpbuf, "struct %s *", lib_structs[i].name);
717
              return copy_string (tmpbuf);
718
            }
719
        }
720
    }
721
  return "?type?";
722
}
723
 
724
void
725
add_decl_to_table (enum decl_types type, void *desc, struct decl_table *table)
726
{
727
  int n = table->nextentry++;
728
 
729
  table->entries[n].type = type;
730
  switch (type)
731
    {
732
    case d_macro:
733
      table->entries[n].decl.macro_d = (struct macro_desc *) desc;
734
      break;
735
    case d_enum:
736
      table->entries[n].decl.enum_d = (struct enum_desc *) desc;
737
      break;
738
    case d_struct:
739
      table->entries[n].decl.struct_d = (struct struct_desc *) desc;
740
      break;
741
    case d_class:
742
      table->entries[n].decl.class_d = (struct class_desc *) desc;
743
      break;
744
    case d_function:
745
      table->entries[n].decl.function_d = (struct function_desc *) desc;
746
      break;
747
    default:
748
      fprintf (stderr, "Unknown decl type %d in add_decl_to_table\n", type);
749
      break;
750
    }
751
  table->entries[n].seq = n;
752
  if (randomize_order)
753
    table->entries[n].order = xrandom (10000);
754
}
755
 
756
/* Create basic definitions of macros.  Negative number of arguments
757
   means a macros that looks like a constant instead of a function.  */
758
 
759
void
760
create_macros (void)
761
{
762
  int i;
763
 
764
  printf ("Creating %d macros...\n", num_macros);
765
  macros =
766
    (struct macro_desc *) xmalloc (num_macros * sizeof(struct macro_desc));
767
  for (i = 0; i < num_macros; ++i)
768
    {
769
      create_macro (&(macros[i]));
770
      add_decl_to_table (d_macro, &(macros[i]), &order);
771
    }
772
 
773
  /* It's important to create library macros second, so that their ids
774
     are higher than those for program macros.  This is so that
775
     library macro bodies are excluded from referencing any program
776
     macros (because of the exclude_id bits in write_expression).  */
777
 
778
  printf ("Creating %d library macros...\n", num_lib_macros);
779
  lib_macros =
780
    (struct macro_desc *) xmalloc (num_lib_macros * sizeof(struct macro_desc));
781
  for (i = 0; i < num_lib_macros; ++i)
782
    {
783
      create_macro (&(lib_macros[i]));
784
      if (!probability(lib_percent))
785
        lib_macros[i].use = 0;
786
      add_decl_to_table (d_macro, &(lib_macros[i]), &lib_order);
787
    }
788
}
789
 
790
void
791
create_macro (struct macro_desc *macrodesc)
792
{
793
  int j, numargs;
794
 
795
  macrodesc->id = next_id++;
796
  macrodesc->name = gen_new_macro_name ();
797
  numargs = xrandom (DEFAULT_MAX_MACRO_ARGS + 1);
798
  --numargs;
799
  if (numargs > 0)
800
    {
801
      macrodesc->args = (char **) xmalloc (numargs * sizeof(char *));
802
      for (j = 0; j < numargs; ++j)
803
        {
804
          macrodesc->args[j] = gen_random_local_name (j, NULL);
805
        }
806
    }
807
  macrodesc->numargs = numargs;
808
  macrodesc->use = 1;
809
}
810
 
811
/* Generate a macro name.  */
812
 
813
char *
814
gen_new_macro_name (void)
815
{
816
  return gen_unique_global_name ("M", (xrandom (3) > 0));
817
}
818
 
819
/* Create definitions of the desired number of enums.  */
820
 
821
void
822
create_enums (void)
823
{
824
  int i;
825
 
826
  printf ("Creating %d enums...\n", num_enums);
827
  enums =
828
    (struct enum_desc *) xmalloc (num_enums * sizeof(struct enum_desc));
829
  for (i = 0; i < num_enums; ++i)
830
    {
831
      create_enum (&(enums[i]));
832
      add_decl_to_table (d_enum, &(enums[i]), &order);
833
    }
834
  printf ("Creating %d library enums...\n", num_lib_enums);
835
  lib_enums =
836
    (struct enum_desc *) xmalloc (num_lib_enums * sizeof(struct enum_desc));
837
  for (i = 0; i < num_lib_enums; ++i)
838
    {
839
      create_enum (&(lib_enums[i]));
840
      if (!probability(lib_percent))
841
        lib_enums[i].use = 0;
842
      add_decl_to_table (d_enum, &(lib_enums[i]), &lib_order);
843
    }
844
}
845
 
846
void
847
create_enum (struct enum_desc *enumdesc)
848
{
849
  int j, num;
850
 
851
  enumdesc->id = next_id++;
852
  /* Let some enums be anonymous. */
853
  if (xrandom (100) < 50)
854
    enumdesc->name = gen_unique_global_name (NULL, 0);
855
  num = num_enumerators / 2 + xrandom (num_enumerators);
856
  if (num <= 0)
857
    num = 1;
858
  enumdesc->enumerators =
859
    (struct enumerator_desc *) xmalloc (num * sizeof(struct enumerator_desc));
860
  for (j = 0; j < num; ++j)
861
    {
862
      enumdesc->enumerators[j].name = gen_random_enumerator_name ();
863
    }
864
  enumdesc->num_enumerators = j;
865
  enumdesc->use = 1;
866
}
867
 
868
/* Generate a unique enumerator within an enum.  */
869
 
870
char *
871
gen_random_enumerator_name (void)
872
{
873
  return gen_unique_global_name ("enum", 0);
874
}
875
 
876
/* Create definitions of the desired number of structures.  */
877
 
878
void
879
create_structs (void)
880
{
881
  int i;
882
 
883
  /* Do the library structs first, so that program structs may use
884
     them in their definitions.  */
885
  printf ("Creating %d library structs...\n", num_lib_structs);
886
  lib_structs =
887
    (struct struct_desc *) xmalloc (num_lib_structs * sizeof(struct struct_desc));
888
  for (i = 0; i < num_lib_structs; ++i)
889
    {
890
      create_struct (&(lib_structs[i]), 1);
891
      if (!probability(lib_percent))
892
        lib_structs[i].use = 0;
893
      add_decl_to_table (d_struct, &(lib_structs[i]), &lib_order);
894
    }
895
 
896
  printf ("Creating %d structs...\n", num_structs);
897
  structs =
898
    (struct struct_desc *) xmalloc (num_structs * sizeof(struct struct_desc));
899
  for (i = 0; i < num_structs; ++i)
900
    {
901
      create_struct (&(structs[i]), 0);
902
      add_decl_to_table (d_struct, &(structs[i]), &order);
903
    }
904
}
905
 
906
void
907
create_struct (struct struct_desc *structdesc, int lib)
908
{
909
  int j, numf;
910
 
911
  structdesc->id = next_id++;
912
  structdesc->name = gen_unique_global_name (NULL, 0);
913
  numf = xrandom (num_fields) + 1;
914
  structdesc->fields =
915
    (struct field_desc *) xmalloc (numf * sizeof(struct field_desc));
916
  for (j = 0; j < numf; ++j)
917
    {
918
      structdesc->fields[j].type = random_type (lib);
919
      structdesc->fields[j].name = gen_random_field_name (j);
920
    }
921
  structdesc->numfields = numf;
922
  structdesc->use = 1;
923
}
924
 
925
char *
926
gen_random_field_name (int n)
927
{
928
  char namebuf[100];
929
 
930
  /* (should have more variety) */
931
  sprintf (namebuf, "field%d", n);
932
  return copy_string (namebuf);
933
}
934
 
935
/* Create definitions of the desired number of classures.  */
936
 
937
void
938
create_classes (void)
939
{
940
  int i;
941
 
942
  /* Do the library classes first, so that program classes may use
943
     them in their definitions.  */
944
  printf ("Creating %d library classes...\n", num_lib_classes);
945
  lib_classes =
946
    (struct class_desc *) xmalloc (num_lib_classes * sizeof(struct class_desc));
947
  for (i = 0; i < num_lib_classes; ++i)
948
    {
949
      create_class (&(lib_classes[i]), 1);
950
      if (!probability(lib_percent))
951
        lib_classes[i].use = 0;
952
      add_decl_to_table (d_class, &(lib_classes[i]), &lib_order);
953
    }
954
 
955
  printf ("Creating %d classes...\n", num_classes);
956
  classes =
957
    (struct class_desc *) xmalloc (num_classes * sizeof(struct class_desc));
958
  for (i = 0; i < num_classes; ++i)
959
    {
960
      create_class (&(classes[i]), 0);
961
      add_decl_to_table (d_class, &(classes[i]), &order);
962
    }
963
}
964
 
965
void
966
create_class (struct class_desc *classdesc, int lib)
967
{
968
  int j, numf, numm;
969
 
970
  classdesc->id = next_id++;
971
  classdesc->name = gen_unique_global_name (NULL, 0);
972
  numf = xrandom (num_fields) + 1;
973
  classdesc->fields =
974
    (struct field_desc *) xmalloc (numf * sizeof(struct field_desc));
975
  for (j = 0; j < numf; ++j)
976
    {
977
      classdesc->fields[j].type = random_type (lib);
978
      classdesc->fields[j].name = gen_random_field_name (j);
979
    }
980
  classdesc->numfields = numf;
981
  numm = xrandom (num_methods + 1);
982
  classdesc->methods =
983
    (struct function_desc *) xmalloc (numm * sizeof(struct function_desc));
984
  for (j = 0; j < numm; ++j)
985
    {
986
      create_function (&(classdesc->methods[j]), lib);
987
      classdesc->methods[j].class = classdesc;
988
    }
989
  classdesc->nummethods = numm;
990
  classdesc->use = 1;
991
}
992
 
993
/* Create a number of functions with random numbers and types of
994
   arguments. */
995
 
996
void
997
create_functions (void)
998
{
999
  int i;
1000
 
1001
  printf ("Creating %d functions...\n", num_functions);
1002
  functions =
1003
    (struct function_desc *) xmalloc (num_functions * sizeof(struct function_desc));
1004
 
1005
  /* Generate the main program, as the first function.  */
1006
  functions[0].id = next_id++;
1007
  functions[0].name = "main";
1008
  functions[0].return_type = t_int;
1009
  functions[0].numargs = 0;
1010
  functions[0].use = 1;
1011
  add_decl_to_table (d_function, &(functions[0]), &order);
1012
 
1013
  /* Generate all the other functions.  */
1014
  for (i = 1; i < num_functions; ++i)
1015
    {
1016
      create_function (&(functions[i]), 0);
1017
      add_decl_to_table (d_function, &(functions[i]), &order);
1018
#if 0 /* use forward decls for now instead */
1019
      {
1020
        int j, type;
1021
        struct function_desc *fndesc = &(functions[i]);
1022
 
1023
        for (j = 0; j < fndesc->numargs; ++j)
1024
          {
1025
            type = fndesc->args[i].type;
1026
            if (type >= t_first_user)
1027
              {
1028
                /* (should find arg types and increase fndesc->order) */
1029
              }
1030
          }
1031
      }
1032
#endif
1033
    }
1034
 
1035
  printf ("Creating %d library functions...\n", num_lib_functions);
1036
  lib_functions =
1037
    (struct function_desc *) xmalloc (num_lib_functions * sizeof(struct function_desc));
1038
  for (i = 0; i < num_lib_functions; ++i)
1039
    {
1040
      create_function (&(lib_functions[i]), 1);
1041
      /* Mark some functions as not to be referenced from the program.  */
1042
      if (!probability(lib_percent))
1043
        lib_functions[i].use = 0;
1044
      add_decl_to_table (d_function, &(lib_functions[i]), &lib_order);
1045
    }
1046
}
1047
 
1048
/* Generate the details of a single function.  */
1049
 
1050
void
1051
create_function (struct function_desc *fndesc, int lib)
1052
{
1053
  int j, range, numargs;
1054
 
1055
  fndesc->id = next_id++;
1056
  fndesc->name = gen_unique_global_name ("fn", 0);
1057
  fndesc->return_type = ((xrandom (4) == 0) ? t_void : random_type (lib));
1058
  /* Choose the number of arguments, preferring shorter argument lists
1059
     by using a simple binomial distribution that is "folded" in the
1060
     middle so zero-arg functions are the most common.  */
1061
  range = 2 * (max_function_args + 1);
1062
  numargs = 0;
1063
  for (j = 0; j < 6; ++j)
1064
    numargs += xrandom (range + 1);
1065
  if (j > 0)
1066
    numargs /= j;
1067
  /* Shift distribution so 0 is in the middle.  */
1068
  numargs -= max_function_args;
1069
  /* Fold negative values over to positive side.  */
1070
  if (numargs < 0)
1071
    numargs = -numargs;
1072
  if (numargs > max_function_args)
1073
    numargs = max_function_args;
1074
  if (numargs > 0)
1075
    {
1076
      fndesc->args =
1077
        (struct arg_desc *) xmalloc (numargs * sizeof(struct arg_desc));
1078
      for (j = 0; j < numargs; ++j)
1079
        {
1080
          fndesc->args[j].type = random_type (lib);
1081
          fndesc->args[j].name = gen_random_local_name (j, NULL);
1082
        }
1083
    }
1084
  fndesc->numargs = numargs;
1085
  fndesc->class = NULL;
1086
  fndesc->use = 1;
1087
}
1088
 
1089
int
1090
compare_entries(const void *x1, const void *x2)
1091
{
1092
  struct decl_entry *e1 = (struct decl_entry *) x1;
1093
  struct decl_entry *e2 = (struct decl_entry *) x2;
1094
 
1095
  if (e1->order != e2->order)
1096
    return (e1->order - e2->order);
1097
  /* Randomized order may have pairs of matching numbers, so use this
1098
     as fallback.  */
1099
  return (e1->seq - e2->seq);
1100
}
1101
 
1102
void
1103
write_header_file (int n)
1104
{
1105
  int i;
1106
  char tmpbuf[100];
1107
  FILE *fp;
1108
 
1109
  sprintf (tmpbuf, "%s%d.h", file_base_name, n);
1110
  fp = fopen (tmpbuf, "w");
1111
  if (fp == NULL)
1112
    return;
1113
  write_description_block (fp);
1114
  if (commenting > 0)
1115
    fprintf (fp, "/* header */\n");
1116
  /* Ensure that structure decls exist before functions mentioning them.  */
1117
  if (randomize_order)
1118
    {
1119
      fprintf (fp, "/* forward decls */\n");
1120
      for (i = 0; i < num_structs; ++i)
1121
        fprintf (fp, "struct %s;\n", structs[i].name);
1122
      for (i = 0; i < num_classes; ++i)
1123
        fprintf (fp, "class %s;\n", classes[i].name);
1124
      fprintf (fp, "\n");
1125
    }
1126
  qsort(order.entries, order.size, sizeof(struct decl_entry),
1127
        compare_entries);
1128
  for (i = 0; i < order.size; ++i)
1129
    {
1130
      switch (order.entries[i].type)
1131
        {
1132
        case d_macro:
1133
          write_macro (fp, order.entries[i].decl.macro_d);
1134
          break;
1135
        case d_enum:
1136
          write_enum (fp, order.entries[i].decl.enum_d);
1137
          break;
1138
        case d_struct:
1139
          write_struct (fp, order.entries[i].decl.struct_d);
1140
          break;
1141
        case d_class:
1142
          write_class (fp, order.entries[i].decl.class_d);
1143
          break;
1144
        case d_function:
1145
          write_function_decl (fp, order.entries[i].decl.function_d);
1146
          break;
1147
        default:
1148
          fprintf (stderr, "Unknown decl type %d in write_header_file\n",
1149
                   order.entries[i].type);
1150
          break;
1151
        }
1152
    }
1153
  fclose (fp);
1154
}
1155
 
1156
void
1157
write_lib_header_file (void)
1158
{
1159
  int i;
1160
  char tmpbuf[100];
1161
  FILE *fp;
1162
 
1163
  sprintf (tmpbuf, "%slib.h", file_base_name);
1164
  fp = fopen (tmpbuf, "w");
1165
  if (fp == NULL)
1166
    return;
1167
  if (commenting > 0)
1168
    fprintf (fp, "/* library header */\n");
1169
  write_description_block (fp);
1170
  /* Ensure that structure decls exist before functions mentioning them.  */
1171
  if (randomize_order)
1172
    {
1173
      fprintf (fp, "/* forward decls */\n");
1174
      for (i = 0; i < num_lib_structs; ++i)
1175
        fprintf (fp, "struct %s;\n", lib_structs[i].name);
1176
      for (i = 0; i < num_lib_classes; ++i)
1177
        fprintf (fp, "class %s;\n", lib_classes[i].name);
1178
      fprintf (fp, "\n");
1179
    }
1180
  qsort(lib_order.entries, lib_order.size, sizeof(struct decl_entry),
1181
        compare_entries);
1182
  for (i = 0; i < lib_order.size; ++i)
1183
    {
1184
      switch (lib_order.entries[i].type)
1185
        {
1186
        case d_macro:
1187
          write_macro (fp, lib_order.entries[i].decl.macro_d);
1188
          break;
1189
        case d_enum:
1190
          write_enum (fp, lib_order.entries[i].decl.enum_d);
1191
          break;
1192
        case d_struct:
1193
          write_struct (fp, lib_order.entries[i].decl.struct_d);
1194
          break;
1195
        case d_class:
1196
          write_class (fp, lib_order.entries[i].decl.class_d);
1197
          break;
1198
        case d_function:
1199
          write_function_decl (fp, lib_order.entries[i].decl.function_d);
1200
          break;
1201
        default:
1202
          fprintf (stderr, "Unknown decl type %d in write_header_file\n",
1203
                   lib_order.entries[i].type);
1204
          break;
1205
        }
1206
    }
1207
  fclose (fp);
1208
}
1209
 
1210
void
1211
write_macro (FILE *fp, struct macro_desc *macrodesc)
1212
{
1213
  int j;
1214
 
1215
  fprintf (fp, "\n#define %s", macrodesc->name);
1216
  /* Negative # arguments indicates an argumentless macro instead of
1217
     one with zero arguments. */
1218
  if (macrodesc->numargs >= 0)
1219
    {
1220
      fprintf (fp, "(");
1221
      for (j = 0; j < macrodesc->numargs; ++j)
1222
        {
1223
          if (j > 0)
1224
            fprintf (fp, ",");
1225
          fprintf (fp, "%s", macrodesc->args[j]);
1226
        }
1227
      fprintf (fp, ")");
1228
    }
1229
  /* Generate a macro body. */
1230
  fprintf (fp, " (");
1231
  switch (xrandom(4))
1232
    {
1233
    case 0:
1234
      write_expression (fp, t_int, 0, 2, macrodesc->id);
1235
      break;
1236
    case 1:
1237
      /* A very common expansion for macros.  */
1238
      fprintf (fp, "0");
1239
      break;
1240
    case 2:
1241
      /* Likewise.  */
1242
      fprintf (fp, "1");
1243
      break;
1244
    default:
1245
      fprintf (fp, "%d", xrandom (100));
1246
      break;
1247
    }
1248
  fprintf (fp, ")");
1249
  fprintf (fp, "\n\n");
1250
}
1251
 
1252
/* Write out the definition of a enum. */
1253
 
1254
void
1255
write_enum (FILE *fp, struct enum_desc *enumdesc)
1256
{
1257
  int j;
1258
 
1259
  fprintf (fp, "\nenum");
1260
  if (enumdesc->name)
1261
    fprintf (fp, " %s", enumdesc->name);
1262
  fprintf (fp, " {");
1263
  for (j = 0; j < enumdesc->num_enumerators; ++j)
1264
    {
1265
      if (j > 0)
1266
        fprintf (fp, ",");
1267
      fprintf (fp, "\n  %s", enumdesc->enumerators[j].name);
1268
    }
1269
  fprintf (fp, "\n};\n\n");
1270
}
1271
 
1272
/* Write out the definition of a structure. */
1273
 
1274
void
1275
write_struct (FILE *fp, struct struct_desc *structdesc)
1276
{
1277
  int j;
1278
 
1279
  fprintf (fp, "\nstruct %s {\n", structdesc->name);
1280
  for (j = 0; j < structdesc->numfields; ++j)
1281
    {
1282
      fprintf (fp, "  %s %s;\n",
1283
               name_from_type (structdesc->fields[j].type),
1284
               structdesc->fields[j].name);
1285
    }
1286
  fprintf (fp, "};\n\n");
1287
}
1288
 
1289
/* Write out the definition of a classure. */
1290
 
1291
void
1292
write_class (FILE *fp, struct class_desc *classdesc)
1293
{
1294
  int j;
1295
 
1296
  fprintf (fp, "\nclass %s {\n", classdesc->name);
1297
  fprintf (fp, "public:\n");
1298
  for (j = 0; j < classdesc->numfields; ++j)
1299
    {
1300
      fprintf (fp, "  %s %s;\n",
1301
               name_from_type (classdesc->fields[j].type),
1302
               classdesc->fields[j].name);
1303
    }
1304
  for (j = 0; j < classdesc->nummethods; ++j)
1305
    {
1306
      write_function (fp, &(classdesc->methods[j]));
1307
    }
1308
  fprintf (fp, "};\n\n");
1309
}
1310
 
1311
void
1312
write_function_decl (FILE *fp, struct function_desc *fndesc)
1313
{
1314
  int i;
1315
 
1316
  fprintf (fp, "extern %s %s (",
1317
           name_from_type (fndesc->return_type), fndesc->name);
1318
  if (language != knr)
1319
    {
1320
      for (i = 0; i < fndesc->numargs; ++i)
1321
        {
1322
          fprintf (fp, "%s %s",
1323
                   name_from_type (fndesc->args[i].type),
1324
                   fndesc->args[i].name);
1325
          if (i + 1 < fndesc->numargs)
1326
            fprintf (fp, ", ");
1327
        }
1328
    }
1329
  fprintf (fp, ");\n");
1330
}
1331
 
1332
/* Write a complete source file. */
1333
 
1334
void
1335
write_source_file (int n)
1336
{
1337
  char tmpbuf[100];
1338
  int j;
1339
  FILE *fp;
1340
 
1341
  sprintf (tmpbuf, "%s%d.%s",
1342
           file_base_name, n, extensions[language]);
1343
  fp = fopen (tmpbuf, "w");
1344
  if (fp == NULL)
1345
    return;
1346
  write_description_block (fp);
1347
  if (1 /*num_lib_header_files*/ > 0)
1348
    {
1349
      for (j = 0; j < 1 /*num_header_files*/; ++j)
1350
        {
1351
          fprintf (fp, "#include \"%slib.h\"\n", file_base_name);
1352
        }
1353
      fprintf (fp, "\n");
1354
    }
1355
  if (num_header_files > 0)
1356
    {
1357
      for (j = 0; j < num_header_files; ++j)
1358
        {
1359
          fprintf (fp, "#include \"%s%d.h\"\n", file_base_name, j);
1360
        }
1361
      fprintf (fp, "\n");
1362
    }
1363
 
1364
  if (n == 0)
1365
    printf ("  (Each file contains %d functions)\n",
1366
            num_functions_per_file);
1367
 
1368
  for (j = 0; j < num_functions_per_file; ++j)
1369
    {
1370
      write_function (fp, &(functions[n * num_functions_per_file + j]));
1371
    }
1372
  fclose (fp);
1373
}
1374
 
1375
/* (should add option to define methods separately) */
1376
 
1377
void
1378
write_function (FILE *fp, struct function_desc *fndesc)
1379
{
1380
  int i, k;
1381
 
1382
  if (fndesc->class)
1383
    fprintf (fp, "  ");
1384
  fprintf (fp, "%s", name_from_type (fndesc->return_type));
1385
  fprintf (fp, (fndesc->class ? " " : "\n"));
1386
  fprintf (fp, "%s (", fndesc->name);
1387
  for (i = 0; i < fndesc->numargs; ++i)
1388
    {
1389
      if (language != knr)
1390
        {
1391
          fprintf (fp, "%s ", name_from_type (fndesc->args[i].type));
1392
        }
1393
      fprintf (fp, "%s", fndesc->args[i].name);
1394
      if (i + 1 < fndesc->numargs)
1395
        fprintf (fp, ", ");
1396
    }
1397
  fprintf(fp, ")");
1398
  fprintf (fp, (fndesc->class ? " " : "\n"));
1399
  if (language == knr)
1400
    {
1401
      for (i = 0; i < fndesc->numargs; ++i)
1402
        {
1403
          fprintf (fp, "%s %s;\n",
1404
                   name_from_type (fndesc->args[i].type),
1405
                   fndesc->args[i].name);
1406
        }
1407
    }
1408
  fprintf(fp, "{");
1409
  fprintf (fp, (fndesc->class ? " " : "\n"));
1410
  if (fndesc->class)
1411
    {
1412
      /* (should generate something for the method sometimes) */
1413
    }
1414
  else
1415
    {
1416
      /* Generate a plausible function body by writing a number of
1417
         statements. */
1418
      for (k = 0; k < function_length; ++k)
1419
        {
1420
          write_statement (fp, 1, function_depth - 1 + xrandom (3));
1421
        }
1422
    }
1423
  /* Write a return statement if appropriate.  */
1424
  if (fndesc->return_type != t_void)
1425
    {
1426
      fprintf (fp, "  return 0;");
1427
      fprintf (fp, (fndesc->class ? " " : "\n"));
1428
    }
1429
  fprintf (fp, "}");
1430
  if (fndesc->class)
1431
    fprintf (fp, ";");
1432
  fprintf (fp, "\n");
1433
}
1434
 
1435
/* Write "library source", which really just means empty function
1436
   bodies, done so the program will link.  */
1437
 
1438
void
1439
write_lib_source_file (void)
1440
{
1441
  char tmpbuf[100];
1442
  int j;
1443
  FILE *fp;
1444
 
1445
  sprintf (tmpbuf, "%slib.%s", file_base_name, extensions[language]);
1446
  fp = fopen (tmpbuf, "w");
1447
  if (fp == NULL)
1448
    return;
1449
  write_description_block (fp);
1450
  if (1 /*num_lib_header_files*/ > 0)
1451
    {
1452
      for (j = 0; j < 1 /*num_lib_header_files*/; ++j)
1453
        {
1454
          fprintf (fp, "#include \"%slib.h\"\n", file_base_name);
1455
        }
1456
      fprintf (fp, "\n");
1457
    }
1458
 
1459
  for (j = 0; j < num_lib_functions; ++j)
1460
    {
1461
      write_lib_function (fp, j);
1462
    }
1463
  fclose (fp);
1464
}
1465
 
1466
/* Generate empty bodies for library function definitions.  */
1467
 
1468
void
1469
write_lib_function (FILE *fp, int n)
1470
{
1471
  int i;
1472
 
1473
  fprintf (fp, "%s\n%s (",
1474
           name_from_type (lib_functions[n].return_type),
1475
           lib_functions[n].name);
1476
  for (i = 0; i < lib_functions[n].numargs; ++i)
1477
    {
1478
      if (language != knr)
1479
        {
1480
          fprintf (fp, "%s ", name_from_type (lib_functions[n].args[i].type));
1481
        }
1482
      fprintf (fp, "%s", lib_functions[n].args[i].name);
1483
      if (i + 1 < lib_functions[n].numargs)
1484
        fprintf (fp, ", ");
1485
    }
1486
  fprintf (fp, ")");
1487
  if (!lib_functions[n].use)
1488
    fprintf (fp, " /* unused */");
1489
  fprintf (fp, "\n");
1490
  if (language == knr)
1491
    {
1492
      for (i = 0; i < lib_functions[n].numargs; ++i)
1493
        {
1494
          fprintf (fp, "%s %s;\n",
1495
                   name_from_type (lib_functions[n].args[i].type),
1496
                   lib_functions[n].args[i].name);
1497
        }
1498
    }
1499
  fprintf (fp, "{\n");
1500
  if (lib_functions[n].return_type != t_void)
1501
    fprintf (fp, "  return 0;\n");
1502
  fprintf (fp, "}\n\n");
1503
}
1504
 
1505
void
1506
write_statement (FILE *fp, int depth, int max_depth)
1507
{
1508
  int i;
1509
 
1510
  for (i = 0; i < depth; ++i)
1511
    fprintf (fp, "  ");
1512
  /* Always do non-recursive statements if going too deep. */
1513
  if (depth >= max_depth)
1514
    {
1515
      write_expression (fp, t_void, 0, xrandom(4) + 1, 0);
1516
      fprintf (fp, ";\n");
1517
      return;
1518
    }
1519
  switch (xrandom(2))
1520
    {
1521
    case 0:
1522
      write_expression (fp, t_void, 0, xrandom(4) + 1, 0);
1523
      fprintf (fp, ";");
1524
      break;
1525
    case 1:
1526
      fprintf (fp, "if (");
1527
      write_expression (fp, t_int, 0, xrandom(2) + 1, 0);
1528
      fprintf (fp, ") {\n");
1529
      write_statement(fp, depth + 1, max_depth);
1530
      for (i = 0; i < depth; ++i)
1531
        fprintf (fp, "  ");
1532
      fprintf (fp, "}");
1533
      break;
1534
    }
1535
  fprintf(fp, "\n");
1536
}
1537
 
1538
/* Write a single expression. */
1539
 
1540
void cast_integer_type (FILE *fp, int type);
1541
struct function_desc *find_function (int rslttype,
1542
                                     struct function_desc *fns, int numfns);
1543
struct macro_desc *find_macro (int rslttype,
1544
                               struct macro_desc *macs, int nummacros,
1545
                               int exclude_id);
1546
 
1547
void
1548
write_expression (FILE *fp, int rslttype, int depth, int max_depth,
1549
                  int exclude_id)
1550
{
1551
  int n, n2, j;
1552
  struct macro_desc *macrodesc;
1553
  struct function_desc *fndesc;
1554
 
1555
  /* Always do non-recursive statements if going too deep. */
1556
  if (depth >= max_depth)
1557
    {
1558
      switch (xrandom(10))
1559
        {
1560
        case 7:
1561
          cast_integer_type (fp, rslttype);
1562
          fprintf (fp, "%d", xrandom (1000));
1563
          break;
1564
        default:
1565
          cast_integer_type (fp, rslttype);
1566
          fprintf (fp, "%d", xrandom (127));
1567
          break;
1568
        }
1569
      return;
1570
    }
1571
  switch (xrandom(10))
1572
    {
1573
    case 0:
1574
      fndesc = find_function (rslttype, lib_functions, num_lib_functions);
1575
      if (fndesc == NULL)
1576
        {
1577
          cast_integer_type (fp, rslttype);
1578
          fprintf (fp, "%d", xrandom (100));
1579
          return;
1580
        }
1581
      fprintf (fp, "%s (", fndesc->name);
1582
      for (j = 0; j < fndesc->numargs; ++j)
1583
        {
1584
          if (j > 0)
1585
            fprintf (fp, ", ");
1586
          write_expression (fp, fndesc->args[j].type, depth + 1,
1587
                            max_depth - 1, exclude_id);
1588
        }
1589
      fprintf(fp, ")");
1590
      break;
1591
    case 7:
1592
      fndesc = find_function (rslttype, functions, num_functions);
1593
      if (fndesc == NULL)
1594
        {
1595
          cast_integer_type (fp, rslttype);
1596
          fprintf (fp, "%d", xrandom (100));
1597
          return;
1598
        }
1599
      fprintf (fp, "%s (", fndesc->name);
1600
      for (j = 0; j < fndesc->numargs; ++j)
1601
        {
1602
          if (j > 0)
1603
            fprintf (fp, ", ");
1604
          write_expression (fp, fndesc->args[j].type, depth + 1,
1605
                            max_depth - 1, exclude_id);
1606
        }
1607
      fprintf(fp, ")");
1608
      break;
1609
    case 1:
1610
    case 6:
1611
      macrodesc = find_macro (t_int, lib_macros, num_lib_macros, exclude_id);
1612
      if (macrodesc == NULL)
1613
        {
1614
          cast_integer_type (fp, rslttype);
1615
          fprintf (fp, "%d", xrandom (100));
1616
          return;
1617
        }
1618
      cast_integer_type (fp, rslttype);
1619
      fprintf (fp, "%s", macrodesc->name);
1620
      if (macrodesc->numargs >= 0)
1621
        {
1622
          fprintf (fp, " (");
1623
          for (j = 0; j < macrodesc->numargs; ++j)
1624
            {
1625
              if (j > 0)
1626
                fprintf (fp, ", ");
1627
              write_expression (fp, t_int, depth + 1, max_depth - 1,
1628
                                exclude_id);
1629
            }
1630
          fprintf (fp, ")");
1631
        }
1632
      break;
1633
    case 8:
1634
      macrodesc = find_macro (t_int, macros, num_macros, exclude_id);
1635
      if (macrodesc == NULL)
1636
        {
1637
          cast_integer_type (fp, rslttype);
1638
          fprintf (fp, "%d", xrandom (100));
1639
          return;
1640
        }
1641
      cast_integer_type (fp, rslttype);
1642
      fprintf (fp, "%s", macrodesc->name);
1643
      if (macrodesc->numargs >= 0)
1644
        {
1645
          fprintf (fp, " (");
1646
          for (j = 0; j < macrodesc->numargs; ++j)
1647
            {
1648
              if (j > 0)
1649
                fprintf (fp, ", ");
1650
              write_expression (fp, t_int, depth + 1, max_depth - 1,
1651
                                exclude_id);
1652
            }
1653
          fprintf (fp, ")");
1654
        }
1655
      break;
1656
    case 2:
1657
      cast_integer_type (fp, rslttype);
1658
      fprintf (fp, "(");
1659
      write_expression (fp, t_int, depth + 1, max_depth, exclude_id);
1660
      fprintf (fp, " + ");
1661
      write_expression (fp, t_int, depth + 1, max_depth, exclude_id);
1662
      fprintf (fp, ")");
1663
      break;
1664
    case 3:
1665
      cast_integer_type (fp, rslttype);
1666
      fprintf (fp, "(");
1667
      write_expression (fp, t_int, depth + 1, max_depth, exclude_id);
1668
      fprintf (fp, " - ");
1669
      write_expression (fp, t_int, depth + 1, max_depth, exclude_id);
1670
      fprintf (fp, ")");
1671
      break;
1672
    case 4:
1673
      cast_integer_type (fp, rslttype);
1674
      fprintf (fp, "(");
1675
      write_expression (fp, t_int, depth + 1, max_depth, exclude_id);
1676
      fprintf (fp, " * ");
1677
      write_expression (fp, t_int, depth + 1, max_depth, exclude_id);
1678
      fprintf (fp, ")");
1679
      break;
1680
    case 5:
1681
      cast_integer_type (fp, rslttype);
1682
      n = xrandom (num_enums);
1683
      n2 = xrandom (enums[n].num_enumerators);
1684
      fprintf (fp, "%s", enums[n].enumerators[n2].name);
1685
      break;
1686
    default:
1687
      cast_integer_type (fp, rslttype);
1688
      fprintf (fp, "%d", xrandom (127));
1689
      break;
1690
    }
1691
}
1692
 
1693
void
1694
cast_integer_type (FILE *fp, int type)
1695
{
1696
  if (type == t_void || type == t_int)
1697
    return;
1698
  fprintf (fp, "(%s) ", name_from_type (type));
1699
}
1700
 
1701
struct macro_desc *
1702
find_macro (int rslttype, struct macro_desc *macs, int nummacros,
1703
            int exclude_id)
1704
{
1705
  int j, n;
1706
 
1707
  for (j = 0; j < 1000; ++j)
1708
    {
1709
      n = xrandom (nummacros);
1710
      if (macs[n].use && macs[n].id > exclude_id)
1711
        return &(macs[n]);
1712
    }
1713
  return NULL;
1714
}
1715
 
1716
/* Find a function that has the right return type.  */
1717
 
1718
struct function_desc *
1719
find_function (int rslttype, struct function_desc *fns, int numfns)
1720
{
1721
  int j, n;
1722
 
1723
  /* Try several times, but eventually give up.  */
1724
  for (j = 0; j < 1000; ++j)
1725
    {
1726
      n = xrandom (numfns);
1727
      if (fns[n].use && fns[n].return_type == rslttype)
1728
        return &(fns[n]);
1729
    }
1730
  return NULL;
1731
}
1732
 
1733
/* Write out a comment block that lists all the parameters used to
1734
   generate this program.  */
1735
 
1736
void
1737
write_description_block (FILE *fp)
1738
{
1739
  extern unsigned long initial_randstate;
1740
 
1741
  fprintf (fp, "/* A fine software product by SPU %s.  */\n",
1742
           version_string);
1743
  fprintf (fp, "/* Written in %s. */\n", lang_names[language]);
1744
  fprintf (fp, "/* Program: %d macros, %d enums, %d structs, %d classes, %d functions, */\n",
1745
           num_macros, num_enums, num_structs, num_classes, num_functions);
1746
  fprintf (fp, "/* divided into %d source file(s) and %d header(s).  */\n",
1747
           num_files, num_header_files);
1748
  fprintf (fp, "/* Library: %d macros, %d enums, %d structs, %d classes, %d functions. */\n",
1749
           num_lib_macros, num_lib_enums, num_lib_structs, num_lib_classes,
1750
           num_lib_functions);
1751
  fprintf (fp, "/* Enumerators per enum range from %d to %d.  */\n",
1752
           num_enumerators / 2, num_enumerators + 1);
1753
  fprintf (fp, "/* Fields per struct/class range from %d to %d.  */\n",
1754
           1, num_fields);
1755
  if (num_classes > 0 || num_lib_classes > 0)
1756
    fprintf (fp, "/* Methods per class range from %d to %d.  */\n",
1757
             0, num_methods);
1758
  fprintf (fp, "/* Function length is %d statements, expression depth is %d.  */\n",
1759
           function_length, function_depth);
1760
  fprintf (fp, "/* Random seed is %d.  */\n", (int) initial_randstate);
1761
  fprintf (fp, "\n");
1762
}
1763
 
1764
/* Write out a makefile that will compile the program just generated. */
1765
 
1766
void
1767
write_makefile (void)
1768
{
1769
  char tmpbuf[100];
1770
  int i, j;
1771
  FILE *fp;
1772
 
1773
  sprintf (tmpbuf, "%s.mk", file_base_name);
1774
  fp = fopen (tmpbuf, "w");
1775
  if (fp)
1776
    {
1777
      /* Name the compiler so we can change it easily.  */
1778
      fprintf (fp, "CC = cc\n\n");
1779
      /* Write dependencies and action line for the executable.  */
1780
      fprintf (fp, "%s.out:     ", file_base_name);
1781
      for (i = 0; i < num_files; ++i)
1782
        fprintf (fp, " %s%d.o", file_base_name, i);
1783
      fprintf (fp, " %slib.o", file_base_name);
1784
      fprintf (fp, "\n");
1785
      fprintf (fp, "\t$(CC) -o %s.out", file_base_name);
1786
      for (i = 0; i < num_files; ++i)
1787
        fprintf (fp, " %s%d.o", file_base_name, i);
1788
      fprintf (fp, " %slib.o", file_base_name);
1789
      fprintf (fp, "\n\n");
1790
      /* Write dependencies for individual files. */
1791
      for (i = 0; i < num_files; ++i)
1792
        {
1793
          fprintf (fp, " %s%d.o:        %s%d.%s",
1794
                   file_base_name, i, file_base_name, i,
1795
                   extensions[language]);
1796
          for (j = 0; j < num_header_files; ++j)
1797
            fprintf (fp, " %s%d.h", file_base_name, j);
1798
          fprintf (fp, "\n");
1799
          fprintf (fp, "\t$(CC) -c %s%d.%s\n",
1800
                   file_base_name, i, extensions[language]);
1801
        }
1802
 
1803
      /* Library stuff.  */
1804
      fprintf (fp, "\nlib:      %slib.o\n\n", file_base_name);
1805
      fprintf (fp, " %slib.o:   %slib.%s %slib.h",
1806
               file_base_name, file_base_name, extensions[language],
1807
               file_base_name);
1808
      fprintf (fp, "\n");
1809
      fprintf (fp, "\t$(CC) -c %slib.%s\n",
1810
               file_base_name, extensions[language]);
1811
      fclose (fp);
1812
    }
1813
}
1814
 
1815
/* Utility/general functions. */
1816
 
1817
/* Generate a name that is guaranteed to be a valid C/C++ identifier.  */
1818
 
1819
char *
1820
gen_unique_global_name (char *root, int upcase)
1821
{
1822
  int i, j;
1823
  char *str, namebuf[100];
1824
 
1825
  if (global_hash_table == NULL)
1826
    {
1827
      global_hash_table =
1828
        (struct hash_table *) xmalloc (sizeof (struct hash_table));
1829
    }
1830
  str = NULL;
1831
  /* Keep trying until we get a unique name. */
1832
  for (i = 0; i < 10000; ++i)
1833
    {
1834
      gen_random_global_name (root, namebuf);
1835
      if (upcase)
1836
        {
1837
          for (j = 0; namebuf[j] != '\0'; ++j)
1838
            namebuf[j] = toupper (namebuf[j]);
1839
        }
1840
      if (get_from_hash_table (namebuf, global_hash_table) == NULL)
1841
        {
1842
          str = add_to_hash_table (namebuf, global_hash_table);
1843
          break;
1844
        }
1845
    }
1846
  if (str == NULL)
1847
    {
1848
      fprintf (stderr, "Can't get a unique name!\n");
1849
      exit(1);
1850
    }
1851
  return str;
1852
}
1853
 
1854
/* Synthesize a random name that is a valid C/C++ identifier and that
1855
   "looks like" something one might see in a program.  */
1856
 
1857
void
1858
gen_random_global_name (char *root, char *namebuf)
1859
{
1860
  char smallbuf[100];
1861
  int n, i, len;
1862
 
1863
  namebuf[0] = '\0';
1864
  switch (xrandom (4))
1865
    {
1866
    case 0:
1867
      namebuf[0] = 'a' + xrandom (26);
1868
      namebuf[1] = '\0';
1869
      break;
1870
    case 1:
1871
      /* Convert a random number into a string, maybe with some
1872
         underscores thrown in for flavor.  */
1873
      n = xrandom (10000);
1874
      i = 0;
1875
      while (n > 0)
1876
        {
1877
          if (xrandom (6) == 0)
1878
            namebuf[i++] = '_';
1879
          namebuf[i++] = 'a' + (n % 26);
1880
          n /= 26;
1881
        }
1882
      namebuf[i] = '\0';
1883
      break;
1884
    default:
1885
      strcat (namebuf, random_computer_word ());
1886
      break;
1887
    }
1888
  if (root != NULL)
1889
    {
1890
      strcat (namebuf, "_");
1891
      strcat (namebuf, root);
1892
    }
1893
  switch (xrandom (5))
1894
    {
1895
    case 0:
1896
      strcat (namebuf, "_");
1897
      len = strlen (namebuf);
1898
      namebuf[len] = 'a' + xrandom (26);
1899
      namebuf[len + 1] = '\0';
1900
      break;
1901
    case 1:
1902
      strcat (namebuf, "_");
1903
      sprintf (smallbuf, "%d", xrandom (10000));
1904
      strcat (namebuf, smallbuf);
1905
      break;
1906
    case 2:
1907
      n = xrandom (10000);
1908
      len = strlen (namebuf);
1909
      i = len;
1910
      while (n > 0)
1911
        {
1912
          if (xrandom (6) == 0)
1913
            namebuf[i++] = '_';
1914
          namebuf[i++] = 'a' + (n % 26);
1915
          n /= 26;
1916
        }
1917
      namebuf[i] = '\0';
1918
      break;
1919
    default:
1920
      strcat (namebuf, "_");
1921
      strcat (namebuf, random_computer_word ());
1922
      break;
1923
    }
1924
  if (xrandom (5) == 0)
1925
    {
1926
      strcat (namebuf, "_");
1927
      sprintf (smallbuf, "%d", xrandom (10000));
1928
      strcat (namebuf, smallbuf);
1929
    }
1930
#if 0 /* enable to study random name distribution */
1931
  printf ("Try %s\n", namebuf);
1932
#endif
1933
}
1934
 
1935
/* Generate a local variable name. */
1936
 
1937
char *
1938
gen_random_local_name (int numothers, char **others)
1939
{
1940
  char namebuf[100];
1941
 
1942
  sprintf (namebuf, "%s%d",
1943
           (xrandom (2) == 0 ? random_computer_word () : "arg"),
1944
           numothers + 1);
1945
  return copy_string (namebuf);
1946
}
1947
 
1948
/* Generic hash table code. */
1949
 
1950
int
1951
hash_string (char *str)
1952
{
1953
  int i, rslt;
1954
 
1955
  rslt = 0;
1956
  for (i = 0; str[i] != '\0'; ++i)
1957
    {
1958
      rslt ^= str[i];
1959
      rslt %= 253;
1960
    }
1961
  return rslt;
1962
}
1963
 
1964
struct hash_entry *
1965
get_hash_entry (void)
1966
{
1967
  return (struct hash_entry *) xmalloc (sizeof (struct hash_entry));
1968
}
1969
 
1970
char *
1971
add_to_hash_table (char *buf, struct hash_table *table)
1972
{
1973
  int hash;
1974
  struct hash_entry *ent, *lastent;
1975
 
1976
  if (buf == NULL)
1977
    buf = "";
1978
  ++(table->numadds);
1979
  hash = hash_string (buf);
1980
  if (table->entries[hash] == NULL)
1981
    {
1982
      table->entries[hash] = get_hash_entry ();
1983
      table->entries[hash]->val = copy_string (buf);
1984
      return table->entries[hash]->val;
1985
    }
1986
  else
1987
    {
1988
      for (ent = table->entries[hash]; ent != NULL; ent = ent->next)
1989
        {
1990
          if (ent->val == NULL)
1991
            return "null!?!";
1992
          if (strcmp (buf, ent->val) == 0)
1993
            return ent->val;
1994
          lastent = ent;
1995
        }
1996
      if (lastent != NULL)
1997
        {
1998
          lastent->next = get_hash_entry ();
1999
          lastent->next->val = copy_string (buf);
2000
          return lastent->next->val;
2001
        }
2002
    }
2003
  /* should never happen */
2004
  return "?!hash!?";
2005
}
2006
 
2007
char *
2008
get_from_hash_table (char *buf, struct hash_table *table)
2009
{
2010
  int hash;
2011
  struct hash_entry *ent, *lastent;
2012
 
2013
  if (buf == NULL)
2014
    buf = "";
2015
  hash = hash_string (buf);
2016
  if (table->entries[hash] == NULL)
2017
    {
2018
      return NULL;
2019
    }
2020
  else
2021
    {
2022
      for (ent = table->entries[hash]; ent != NULL; ent = ent->next)
2023
        {
2024
          if (ent->val == NULL)
2025
            return "null!?!";
2026
          if (strcmp (buf, ent->val) == 0)
2027
            return ent->val;
2028
          lastent = ent;
2029
        }
2030
      if (lastent != NULL)
2031
        {
2032
          return NULL;
2033
        }
2034
    }
2035
  /* should never happen */
2036
  return "?!hash!?";
2037
}
2038
 
2039
/* Random number handling is important but terrible/nonexistent in
2040
   some systems.  Do it ourselves.  Also, this will give repeatable
2041
   results across multiple platforms, which is important if this is
2042
   being used to generate test cases. */
2043
 
2044
/* The random state *must* be at least 32 bits.  */
2045
 
2046
unsigned long initial_randstate = 0;
2047
 
2048
unsigned long randstate = 0;
2049
 
2050
/* Seed can come from elsewhere, for repeatability.  Otherwise, it comes
2051
   from the current time, scaled down to where 32-bit arithmetic won't
2052
   overflow.  */
2053
 
2054
void
2055
init_xrandom (int seed)
2056
{
2057
  time_t tm;
2058
 
2059
  if (seed > 0)
2060
    {
2061
      /* If the random state is already set, changes are somewhat
2062
         suspicious.  */
2063
      if (randstate > 0)
2064
        {
2065
          fprintf (stderr, "Randstate being changed from %lu to %d\n",
2066
                   randstate, seed);
2067
        }
2068
      randstate = seed;
2069
    }
2070
  else
2071
    {
2072
      time (&tm);
2073
      randstate = tm;
2074
    }
2075
  /* Whatever its source, put the randstate into known range (0 - 199999).  */
2076
  randstate = abs (randstate);
2077
  randstate %= 200000;
2078
  /* This is kept around for the sake of error reporting. */
2079
  initial_randstate = randstate;
2080
}
2081
 
2082
/* Numbers lifted from Numerical Recipes, p. 198.  */
2083
/* Arithmetic must be 32-bit.  */
2084
 
2085
int
2086
xrandom (int m)
2087
{
2088
  int rslt;
2089
 
2090
  randstate = (9301 * randstate + 49297) % 233280;
2091
  rslt = (m * randstate) / 233280;
2092
#if 0 /* enable to study random number distribution */
2093
  printf ("# %lu -> %d\n", randstate, rslt);
2094
#endif
2095
  return rslt;
2096
}
2097
 
2098
/* Percentage probability, with bounds checking. */
2099
 
2100
int
2101
probability(int prob)
2102
{
2103
  if (prob <= 0)
2104
    return 0;
2105
  if (prob >= 100)
2106
    return 1;
2107
  return (xrandom (100) < prob);
2108
}
2109
 
2110
char *
2111
xmalloc (int amt)
2112
{
2113
  char *value = (char *) malloc (amt);
2114
 
2115
  if (value == NULL)
2116
    {
2117
      /* This is pretty serious, have to get out quickly.  */
2118
      fprintf (stderr, "Memory exhausted!!\n");
2119
      exit (1);
2120
    }
2121
  /* Save callers from having to clear things themselves.  */
2122
  memset (value, 0, amt);
2123
  return value;
2124
}
2125
 
2126
/* Copy a string to newly-allocated space.  The new space is never
2127
   freed.  */
2128
 
2129
char *
2130
copy_string (char *str)
2131
{
2132
  int len = strlen (str);
2133
  char *rslt;
2134
 
2135
  rslt = xmalloc (len + 1);
2136
  strcpy (rslt, str);
2137
  return rslt;
2138
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.