#include #include #include #include #include #include #include /** * Read whole file into a buffer and return pointer to buffer. * Possibly kind of silly to have both \p file and \p f. * Apparently there's no standardized way to get the file name of a * file pointer. * * @param fname Name of file to read. * @param f File pointer. * @return Pointer to buffer with file contents. */ 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 */ error("%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) { FILE *f = fopen(fname, "rb"); if (!f) { error("failed opening %s: %s\n", fname, strerror(errno)); return -1; } const char *buf = read_file(fname, f); fclose(f); if (!buf) return -1; struct parser *p = create_parser(); if (!p) return -1; parse(p, fname, buf); int ret = p->failed ? -1 : 0; /* eventually do other stuff as well */ free((void *)buf); destroy_parser(p); return ret; }