aboutsummaryrefslogtreecommitdiff
path: root/src/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core.c')
-rw-r--r--src/core.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/core.c b/src/core.c
new file mode 100644
index 0000000..7eca8bd
--- /dev/null
+++ b/src/core.c
@@ -0,0 +1,68 @@
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <posthaste/debug.h>
+#include <posthaste/parser.h>
+#include <posthaste/core.h>
+
+/**
+ * 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;
+}