#include #include #include #include #include #include #include #include #include #include #include #include static char *read_file(const char *fname, FILE *f) { fseek(f, 0, SEEK_END); long s = ftell(f); if (s == LONG_MAX) { /** @todo should probably do this via fstat or something */ fprintf(stderr, "%s might be a directory", fname); return NULL; } fseek(f, 0, SEEK_SET); char *buf = malloc(s + 1); if (!buf) return NULL; fread(buf, s + 1, 1, f); /* remember terminating null */ buf[s] = 0; return buf; } int run(const char *fname) { int ret = 0; const char *buf = NULL; struct scope *scope = NULL; struct parser *p = NULL; FILE *f = fopen(fname, "rb"); if (!f) { fprintf(stderr, "failed opening %s: %s\n", fname, strerror(errno)); return -1; } buf = read_file(fname, f); fclose(f); if (!buf) { ret = -1; goto out; } p = create_parser(); if (!p) { ret = -1; goto out; } parse(p, fname, buf); if (p->failed) { ret = -1; goto out; } scope = create_scope(); if (!scope) { ret = -1; goto out; } scope_set_file(scope, fname, buf); struct ast *ast = p->tree; if (check(scope, ast)) { ret = -1; goto out; } lower_ast(ast); execute(); out: free((void *)buf); destroy_lowering(); destroy_scopes(); destroy_ast_nodes(); destroy_parser(p); return ret; }