📄 spu.c
字号:
numargs = -numargs; if (numargs > max_function_args) numargs = max_function_args; if (numargs > 0) { fndesc->args = (struct arg_desc *) xmalloc (numargs * sizeof(struct arg_desc)); for (j = 0; j < numargs; ++j) { fndesc->args[j].type = random_type (lib); fndesc->args[j].name = gen_random_local_name (j, NULL); } } fndesc->numargs = numargs; fndesc->class = NULL; fndesc->use = 1;}intcompare_entries(const void *x1, const void *x2){ struct decl_entry *e1 = (struct decl_entry *) x1; struct decl_entry *e2 = (struct decl_entry *) x2; if (e1->order != e2->order) return (e1->order - e2->order); /* Randomized order may have pairs of matching numbers, so use this as fallback. */ return (e1->seq - e2->seq);}voidwrite_header_file (int n){ int i; char tmpbuf[100]; FILE *fp; sprintf (tmpbuf, "%s%d.h", file_base_name, n); fp = fopen (tmpbuf, "w"); if (fp == NULL) return; write_description_block (fp); if (commenting > 0) fprintf (fp, "/* header */\n"); /* Ensure that structure decls exist before functions mentioning them. */ if (randomize_order) { fprintf (fp, "/* forward decls */\n"); for (i = 0; i < num_structs; ++i) fprintf (fp, "struct %s;\n", structs[i].name); for (i = 0; i < num_classes; ++i) fprintf (fp, "class %s;\n", classes[i].name); fprintf (fp, "\n"); } qsort(order.entries, order.size, sizeof(struct decl_entry), compare_entries); for (i = 0; i < order.size; ++i) { switch (order.entries[i].type) { case d_macro: write_macro (fp, order.entries[i].decl.macro_d); break; case d_enum: write_enum (fp, order.entries[i].decl.enum_d); break; case d_struct: write_struct (fp, order.entries[i].decl.struct_d); break; case d_class: write_class (fp, order.entries[i].decl.class_d); break; case d_function: write_function_decl (fp, order.entries[i].decl.function_d); break; default: fprintf (stderr, "Unknown decl type %d in write_header_file\n", order.entries[i].type); break; } } fclose (fp);}voidwrite_lib_header_file (void){ int i; char tmpbuf[100]; FILE *fp; sprintf (tmpbuf, "%slib.h", file_base_name); fp = fopen (tmpbuf, "w"); if (fp == NULL) return; if (commenting > 0) fprintf (fp, "/* library header */\n"); write_description_block (fp); /* Ensure that structure decls exist before functions mentioning them. */ if (randomize_order) { fprintf (fp, "/* forward decls */\n"); for (i = 0; i < num_lib_structs; ++i) fprintf (fp, "struct %s;\n", lib_structs[i].name); for (i = 0; i < num_lib_classes; ++i) fprintf (fp, "class %s;\n", lib_classes[i].name); fprintf (fp, "\n"); } qsort(lib_order.entries, lib_order.size, sizeof(struct decl_entry), compare_entries); for (i = 0; i < lib_order.size; ++i) { switch (lib_order.entries[i].type) { case d_macro: write_macro (fp, lib_order.entries[i].decl.macro_d); break; case d_enum: write_enum (fp, lib_order.entries[i].decl.enum_d); break; case d_struct: write_struct (fp, lib_order.entries[i].decl.struct_d); break; case d_class: write_class (fp, lib_order.entries[i].decl.class_d); break; case d_function: write_function_decl (fp, lib_order.entries[i].decl.function_d); break; default: fprintf (stderr, "Unknown decl type %d in write_header_file\n", lib_order.entries[i].type); break; } } fclose (fp);}voidwrite_macro (FILE *fp, struct macro_desc *macrodesc){ int j; fprintf (fp, "\n#define %s", macrodesc->name); /* Negative # arguments indicates an argumentless macro instead of one with zero arguments. */ if (macrodesc->numargs >= 0) { fprintf (fp, "("); for (j = 0; j < macrodesc->numargs; ++j) { if (j > 0) fprintf (fp, ","); fprintf (fp, "%s", macrodesc->args[j]); } fprintf (fp, ")"); } /* Generate a macro body. */ fprintf (fp, " ("); switch (xrandom(4)) { case 0: write_expression (fp, t_int, 0, 2, macrodesc->id); break; case 1: /* A very common expansion for macros. */ fprintf (fp, "0"); break; case 2: /* Likewise. */ fprintf (fp, "1"); break; default: fprintf (fp, "%d", xrandom (100)); break; } fprintf (fp, ")"); fprintf (fp, "\n\n");}/* Write out the definition of a enum. */voidwrite_enum (FILE *fp, struct enum_desc *enumdesc){ int j; fprintf (fp, "\nenum"); if (enumdesc->name) fprintf (fp, " %s", enumdesc->name); fprintf (fp, " {"); for (j = 0; j < enumdesc->num_enumerators; ++j) { if (j > 0) fprintf (fp, ","); fprintf (fp, "\n %s", enumdesc->enumerators[j].name); } fprintf (fp, "\n};\n\n");}/* Write out the definition of a structure. */voidwrite_struct (FILE *fp, struct struct_desc *structdesc){ int j; fprintf (fp, "\nstruct %s {\n", structdesc->name); for (j = 0; j < structdesc->numfields; ++j) { fprintf (fp, " %s %s;\n", name_from_type (structdesc->fields[j].type), structdesc->fields[j].name); } fprintf (fp, "};\n\n");}/* Write out the definition of a classure. */voidwrite_class (FILE *fp, struct class_desc *classdesc){ int j; fprintf (fp, "\nclass %s {\n", classdesc->name); fprintf (fp, "public:\n"); for (j = 0; j < classdesc->numfields; ++j) { fprintf (fp, " %s %s;\n", name_from_type (classdesc->fields[j].type), classdesc->fields[j].name); } for (j = 0; j < classdesc->nummethods; ++j) { write_function (fp, &(classdesc->methods[j])); } fprintf (fp, "};\n\n");}voidwrite_function_decl (FILE *fp, struct function_desc *fndesc){ int i; fprintf (fp, "extern %s %s (", name_from_type (fndesc->return_type), fndesc->name); if (language != knr) { for (i = 0; i < fndesc->numargs; ++i) { fprintf (fp, "%s %s", name_from_type (fndesc->args[i].type), fndesc->args[i].name); if (i + 1 < fndesc->numargs) fprintf (fp, ", "); } } fprintf (fp, ");\n");}/* Write a complete source file. */voidwrite_source_file (int n){ char tmpbuf[100]; int j; FILE *fp; sprintf (tmpbuf, "%s%d.%s", file_base_name, n, extensions[language]); fp = fopen (tmpbuf, "w"); if (fp == NULL) return; write_description_block (fp); if (1 /*num_lib_header_files*/ > 0) { for (j = 0; j < 1 /*num_header_files*/; ++j) { fprintf (fp, "#include \"%slib.h\"\n", file_base_name); } fprintf (fp, "\n"); } if (num_header_files > 0) { for (j = 0; j < num_header_files; ++j) { fprintf (fp, "#include \"%s%d.h\"\n", file_base_name, j); } fprintf (fp, "\n"); } if (n == 0) printf (" (Each file contains %d functions)\n", num_functions_per_file); for (j = 0; j < num_functions_per_file; ++j) { write_function (fp, &(functions[n * num_functions_per_file + j])); } fclose (fp);}/* (should add option to define methods separately) */voidwrite_function (FILE *fp, struct function_desc *fndesc){ int i, k; if (fndesc->class) fprintf (fp, " "); fprintf (fp, "%s", name_from_type (fndesc->return_type)); fprintf (fp, (fndesc->class ? " " : "\n")); fprintf (fp, "%s (", fndesc->name); for (i = 0; i < fndesc->numargs; ++i) { if (language != knr) { fprintf (fp, "%s ", name_from_type (fndesc->args[i].type)); } fprintf (fp, "%s", fndesc->args[i].name); if (i + 1 < fndesc->numargs) fprintf (fp, ", "); } fprintf(fp, ")"); fprintf (fp, (fndesc->class ? " " : "\n")); if (language == knr) { for (i = 0; i < fndesc->numargs; ++i) { fprintf (fp, "%s %s;\n", name_from_type (fndesc->args[i].type), fndesc->args[i].name); } } fprintf(fp, "{"); fprintf (fp, (fndesc->class ? " " : "\n")); if (fndesc->class) { /* (should generate something for the method sometimes) */ } else { /* Generate a plausible function body by writing a number of statements. */ for (k = 0; k < function_length; ++k) { write_statement (fp, 1, function_depth - 1 + xrandom (3)); } } /* Write a return statement if appropriate. */ if (fndesc->return_type != t_void) { fprintf (fp, " return 0;"); fprintf (fp, (fndesc->class ? " " : "\n")); } fprintf (fp, "}"); if (fndesc->class) fprintf (fp, ";"); fprintf (fp, "\n");}/* Write "library source", which really just means empty function bodies, done so the program will link. */voidwrite_lib_source_file (void){ char tmpbuf[100]; int j; FILE *fp; sprintf (tmpbuf, "%slib.%s", file_base_name, extensions[language]); fp = fopen (tmpbuf, "w"); if (fp == NULL) return; write_description_block (fp); if (1 /*num_lib_header_files*/ > 0) { for (j = 0; j < 1 /*num_lib_header_files*/; ++j) { fprintf (fp, "#include \"%slib.h\"\n", file_base_name); } fprintf (fp, "\n"); } for (j = 0; j < num_lib_functions; ++j) { write_lib_function (fp, j); } fclose (fp);}/* Generate empty bodies for library function definitions. */voidwrite_lib_function (FILE *fp, int n){ int i; fprintf (fp, "%s\n%s (", name_from_type (lib_functions[n].return_type), lib_functions[n].name); for (i = 0; i < lib_functions[n].numargs; ++i) { if (language != knr) { fprintf (fp, "%s ", name_from_type (lib_functions[n].args[i].type)); } fprintf (fp, "%s", lib_functions[n].args[i].name); if (i + 1 < lib_functions[n].numargs) fprintf (fp, ", "); } fprintf (fp, ")"); if (!lib_functions[n].use) fprintf (fp, " /* unused */"); fprintf (fp, "\n"); if (language == knr) { for (i = 0; i < lib_functions[n].numargs; ++i) { fprintf (fp, "%s %s;\n", name_from_type (lib_functions[n].args[i].type), lib_functions[n].args[i].name); } } fprintf (fp, "{\n"); if (lib_functions[n].return_type != t_void) fprintf (fp, " return 0;\n"); fprintf (fp, "}\n\n");}voidwrite_statement (FILE *fp, int depth, int max_depth){ int i; for (i = 0; i < depth; ++i) fprintf (fp, " "); /* Always do non-recursive statements if going too deep. */ if (depth >= max_depth) { write_expression (fp, t_void, 0, xrandom(4) + 1, 0); fprintf (fp, ";\n"); return; } switch (xrandom(2)) { case 0: write_expression (fp, t_void, 0, xrandom(4) + 1, 0); fprintf (fp, ";"); break; case 1: fprintf (fp, "if ("); write_expression (fp, t_int, 0, xrandom(2) + 1, 0); fprintf (fp, ") {\n"); write_statement(fp, depth + 1, max_depth); for (i = 0; i < depth; ++i) fprintf (fp, " "); fprintf (fp, "}"); break; } fprintf(fp, "\n");}/* Write a single expression. */void cast_integer_type (FILE *fp, int type);struct function_desc *find_function (int rslttype, struct function_desc *fns, int numfns);struct macro_desc *find_macro (int rslttype, struct macro_desc *macs, int nummacros, int exclude_id);voidwrite_expression (FILE *fp, int rslttype, int depth, int max_depth, int exclude_id){ int n, n2, j; struct macro_desc *macrodesc; struct function_desc *fndesc; /* Always do non-recursive statements if going too deep. */ if (depth >= max_depth) { switch (xrandom(10)) { case 7: cast_integer_type (fp, rslttype); fprintf (fp, "%d", xrandom (1000)); break; default: cast_integer_type (fp, rslttype); fprintf (fp, "%d", xrandom (127)); break; } return; } switch (xrandom(10)) { case 0: fndesc = find_function (rslttype, lib_functions, num_lib_functions); if (fndesc == NULL) { cast_integer_type (fp, rslttype); fprintf (fp, "%d", xrandom (100)); return; } fprintf (fp, "%s (", fndesc->name); for (j = 0; j < fndesc->numargs; ++j) { if (j > 0) fprintf (fp, ", "); write_expression (fp, fndesc->args[j].type, depth + 1, max_depth - 1, exclude_id); } fprintf(fp, ")"); break; case 7: fndesc = find_function (rslttype, functions, num_functions); if (fndesc == NULL) { cast_integer_type (fp, rslttype); fprintf (fp, "%d", xrandom (100)); return; } fprintf (fp, "%s (", fndesc->name); for (j = 0; j < fndesc->numargs; ++j) { if (j > 0) fprintf (fp, ", "); write_expression (fp, fndesc->args[j].type, depth + 1, max_depth - 1, exclude_id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -