/* Call when done with the test file and all data structures associated * with it. Frees the TestSet list returned by parse_test_file(). */ void close_testfile(struct TestFile *tf) { assert(tf != NULL); if (tf->sets) free_sets(tf->sets); if (tf->file_buf) { if (!munmap(tf->file_buf, tf->statbuf.st_size)) { tf->file_buf = NULL; } else { fprintf(stderr, "Unmapping file %s: %s\n", tf->path, strerror(errno)); abort(); } } if (tf->fd && !close(tf->fd)) { tf->fd = 0; tf->path = NULL; } else { fprintf(stderr, "Closing file %s: %s\n", tf->path, strerror(errno)); abort(); } free(tf); }
/* * Main application. * * Args: * [1] -- The path to the kinetics batch file (.bkn) to read. * */ int main(int argc, char **argv) { if (argc != 2) { fprintf(stdout, "Specify a single kinetics file to read.\n"); return EXIT_SUCCESS; } // TODO: Verify file extension? // TODO: Make sure long is big enough for file offsets, if not use size_t kFile file; char *method_prefix = "TContinuumStore"; long method_start = 0; dSet** sets = NULL; int sets_count = 0; // read file into a buffer read_file(&file, argv[1]); while (1) { method_start = buf_find(file.buffer, file.size, method_prefix, 15, method_start); if (method_start == -1) // we're at the end of the file break; sets = (dSet**)realloc(sets, sizeof(dSet*) * (sets_count + 1)); if (sets == NULL) { fprintf(stderr, "Unable to allocate memory for data set %d\n.", sets_count); exit(EXIT_FAILURE); } sets[sets_count] = extract_method_data(&file, method_start); //display_set(sets[sets_count]); sets_count++; } //printf("--------------------------------------------\n"); // output as JSON string char* json = json_serialize(sets, sets_count); fprintf(stdout, "%s\n", json); free(json); free_sets(sets, sets_count); free(file.buffer); //printf("Done.\n"); //printf("Extracted data for %d methods.\n", sets_count); return EXIT_SUCCESS; }
static void free_sets(struct TestSet *set) { if (set->next) free_sets(set->next); if (set->deps) free_deps(set->deps); if (set->setup) free_code(set->setup); if (set->teardown) free_code(set->teardown); if (set->tests) free_cases(set->tests); if (set->code) free_code(set->code); free(set); }
PRIVATE void make_tran(int sstate) { SET *NFA_set; DFA_STATE *current; int nextstate; char *isaccept; int anchor; int c; NFA_set = newset(); put('\n', stderr); free_sets(); }
static struct TestSet *parse_set(struct TestFile *tf) { struct TestSet *set = NEW0(struct TestSet); char *tok; size_t len; assert(tf->next_pos); assert(tf->next_pos > tf->read_pos); set->name = expect_name(tf, &set->name_len, "set"); if (!set->name) goto err; if (expect_eol(tf)) goto err; // set contents: dep, tolerance, setup, teardown, test case, fortran set->tolerance = 0.0; // XXX magic number == BAD for (;;) { tok = next_token(tf, &len); if (tok == END_OF_LINE) { if (!next_line(tf)) { syntax_error(tf); goto err; // EOF } } else if (tok) { if (same_token("dep", 3, tok, len)) { struct TestDependency *dep = parse_dependency(tf); if (!dep) goto err; dep->next = set->deps; set->deps = dep; set->n_deps++; } else if (same_token("use", 3, tok, len)) { struct TestModule *mod = parse_module(tf); if (!mod) goto err; mod->next = set->mods; set->mods = mod; set->n_mods++; } else if (same_token("tolerance", 9, tok, len)) { char *tolend; tok = next_token(tf, &len); if (!tok || tok == END_OF_LINE) { fail(tf, tf->read_pos, "expected tolerance value"); goto err; } set->tolerance = strtod(tf->read_pos, &tolend); if (tolend == tf->read_pos || tolend != tf->next_pos) { fail(tf, tf->read_pos, "not a floating point value"); goto err; } tf->next_pos = tolend; } else if (same_token("setup", 5, tok, len)) { if (set->setup) { fail(tf, tf->next_pos, "more than one setup case specified"); goto err; } set->setup = parse_support(tf, "setup"); if (!set->setup) goto err; } else if (same_token("teardown", 8, tok, len)) { if (set->teardown) { fail(tf, tf->next_pos, "more than one teardown case specified"); goto err; } set->teardown = parse_support(tf, "teardown"); if (!set->teardown) goto err; } else if (same_token("test", 4, tok, len)) { struct TestCase *test = parse_test_case(tf); if (!test) goto err; test->next = set->tests; set->tests = test; set->n_tests++; } else if (same_token("end", 3, tok, len)) { tf->next_pos = tf->read_pos; break; // end of test set } else { // fortran code struct Code *code; tf->next_pos = tf->read_pos = tf->line_pos; code = parse_fortran(tf, NULL); // XXX check for parse fail? code->next = set->code; set->code = code; } } else { // EOF fail(tf, tf->read_pos, "expected end set"); goto err; } } // end set name if (parse_end_sequence(tf, "set", set->name, set->name_len)) goto err; return set; err: free_sets(set); return NULL; }
/* 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; }
/* figure out what dirs we want to process for cleaning and display results. */ int qpkg_clean(char *dirp) { FILE *fp; int i, count; size_t disp_units = 0; uint64_t num_all_bytes; struct dirent **dnames; queue *vdb; vdb = get_vdb_atoms(1); if (chdir(dirp) != 0) { free_sets(vdb); return 1; } if ((count = scandir(".", &dnames, filter_hidden, alphasort)) < 0) { free_sets(vdb); return 1; } if (eclean) { if ((fp = fopen(initialize_ebuild_flat(), "r")) != NULL) { size_t buflen; char *buf; buf = NULL; while (getline(&buf, &buflen, fp) != -1) { char *name, *p; if ((p = strrchr(buf, '.')) == NULL) continue; *p = 0; if ((p = strrchr(buf, '/')) == NULL) continue; *p = 0; name = p + 1; if ((p = strrchr(buf, '/')) == NULL) continue; *p = 0; /* these strcat() are safe. the name is extracted from buf already. */ strcat(buf, "/"); strcat(buf, name); /* num_all_bytes will be off when pretend and eclean are enabled together */ /* vdb = del_set(buf, vdb, &i); */ vdb = add_set(buf, vdb); } free(buf); fclose(fp); } } num_all_bytes = qpkg_clean_dir(dirp, vdb); for (i = 0; i < count; i++) { char buf[_Q_PATH_MAX]; snprintf(buf, sizeof(buf), "%s/%s", dirp, dnames[i]->d_name); num_all_bytes += qpkg_clean_dir(buf, vdb); } scandir_free(dnames, count); free_sets(vdb); disp_units = KILOBYTE; if ((num_all_bytes / KILOBYTE) > 1000) disp_units = MEGABYTE; qprintf(" %s*%s Total space that would be freed in packages directory: %s%s %c%s\n", GREEN, NORM, RED, make_human_readable_str(num_all_bytes, 1, disp_units), disp_units == MEGABYTE ? 'M' : 'K', NORM); return 0; }