static struct TestFile * generate_code(char *infile, char *outfile, const struct Config *conf) { struct TestFile *tf; FILE *fout; int dep_added; tf = parse_test_file(infile); if (!tf) return NULL; if (!tf->sets) { close_testfile(tf); return NULL; } dep_added = file_dependency(infile, tf->sets, conf); // XXX if we're generating code just to run a test, use a mkstemp if (!outfile) { outfile = make_fortran_name(infile, conf); } tf->exe = outfile; fout = fopen(outfile, "w"); if (!fout) { fprintf(stderr, "FUnit: could not open %s for writing\n", outfile); return NULL; } if (generate_code_file(tf->sets, fout)) { close_testfile(tf); return NULL; } if (fclose(fout)) { fprintf(stderr, "FUnit: error closing %s\n", outfile); close_testfile(tf); return NULL; } if (dep_added) { // XXX wtf is this doing? struct TestSet *set = tf->sets; while (set) { set->deps = set->deps->next; set = set->next; } } return tf; }
int main(int argc, char **argv) { struct Config conf; struct Options opts; if (parse_args(argc, argv, &opts)) { return -1; } if (read_config(&conf)) { free_config(&conf); return -1; } while (optind < argc) { printf("generating code from %s to %s\n", argv[optind], opts.outfile); struct TestFile *tf = generate_code(argv[optind], opts.outfile, &conf); if (tf) { if (opts.just_output_fortran) goto pass; printf("building test for %s\n", opts.outfile); build_test(tf, &conf); if (opts.stop_after_build) goto pass; printf("running test %s\n", tf->exe); run_test(tf->exe); pass: close_testfile(tf); } // XXX what does it mean if tf == NULL? optind++; } free_config(&conf); return 0; }
/* Parser entry point. Opens and parses the test sets in the given file. */ struct TestFile *parse_test_file(const char *path) { struct TestFile *tf = NEW0(struct TestFile); tf->fd = open(path, O_RDONLY); if (tf->fd == -1) { fprintf(stderr, "Opening file %s: %s\n", path, strerror(errno)); return NULL; } tf->path = path; if (fstat(tf->fd, &tf->statbuf)) { fprintf(stderr, "Stat file %s: %s\n", path, strerror(errno)); goto close_it; } if (tf->statbuf.st_size < 1) { fprintf(stderr, "File %s is empty!\n", path); goto close_it; } tf->file_buf = (char *)mmap(NULL, tf->statbuf.st_size, PROT_READ, MAP_SHARED, tf->fd, 0); if (!tf->file_buf) { fprintf(stderr, "Mapping file %s: %s\n", path, strerror(errno)); goto close_it; } tf->file_end = tf->file_buf + tf->statbuf.st_size; if (!next_line(tf)) { syntax_error(tf); goto close_it; } for (;;) { size_t toklen; char *token = next_token(tf, &toklen); if (same_token("set", 3, token, toklen)) { struct TestSet *set = parse_set(tf); if (!set) // parse failure already reported goto close_it; set->next = tf->sets; tf->sets = set; } else if (token == END_OF_LINE) { if (!next_line(tf)) { // EOF if (!tf->sets) { goto no_sets; } goto done; } // else swallow blank line } else { no_sets: fail(tf, tf->read_pos, "expected a test set"); goto close_it; } } close_it: if (tf->sets) { free_sets(tf->sets); tf->sets = NULL; } close_testfile(tf); done: return tf; }
static void runtests(GSList* task_list) { size_t i; for (i = 0; i < g_slist_length(task_list); i++){ struct task* task; task = g_slist_nth_data(task_list, i); switch(task->op){ case OPEN: open_testfile(); break; case MANOPEN: manopen_testfile(); break; case CLOSE: close_testfile(); break; case CLOSE_SAVEFD: close_savefd(); break; case WAIT: waitnotice(); break; case SEND: sendnotice(); break; case WRITE: write_testfile(task); break; case READ: read_testfile(task); break; case RUN: test( task->run_param.num, task->run_param.sec, task->run_param.func, task->run_param.offset, task->run_param.length, task->run_param.pass, FATAL); break; case FORK:{ int subpid = fork(); if (subpid < 0){ perror("can't fork off child"); exit(1); } if (subpid == 0){ test( task->run_param.num, task->run_param.sec, task->run_param.func, task->run_param.offset, task->run_param.length, task->run_param.pass, FATAL); while(1) { sleep(1); } }else{ gi.forkpid = subpid; } break; } case KILL: if(kill(gi.forkpid, SIGINT) == -1){ perror("kill"); exit(1); } break; case SLEEP: sleep(task->sleep_param.time); break; case PUSHFD: pushfd(); break; case POPFD: popfd(); break; case TRUNC: hb_trunc(); break; } } }