summaryrefslogtreecommitdiff
path: root/src/source.c
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2026-04-12 20:57:06 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2026-04-12 20:59:39 +0200
commite5af28536bfb0f4c9131df56d2009ba5196f5e3a (patch)
tree3ab928f961a1ccd8440b070d7b57f79146457e8c /src/source.c
downloadanimtool-e5af28536bfb0f4c9131df56d2009ba5196f5e3a.tar.xz
init
Diffstat (limited to 'src/source.c')
-rw-r--r--src/source.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/source.c b/src/source.c
new file mode 100644
index 0000000..cc544e4
--- /dev/null
+++ b/src/source.c
@@ -0,0 +1,59 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "source.h"
+
+void source_init(struct source *src, str name, str contents)
+{
+ src->name = name;
+ src->offset = 0;
+ src->contents = contents;
+ src->strings.len = src->strings.cap = 0;
+ src->strings.ptr = nullptr;
+}
+
+void source_error(struct source *src, struct range loc, const char *fmt, ...)
+{
+ char *p_start = src->contents.ptr + loc.start;
+ char *p_end = src->contents.ptr + loc.end;
+
+ unsigned int lineno = 0;
+ str iter = src->contents;
+ str line;
+ do {
+ line = str_walk(&iter, S("\n"));
+ lineno++;
+ } while (line.ptr + line.len <= p_start);
+
+ fprintf(stderr, "parse error in %.*s:%u: ", PSTR(src->name), lineno);
+
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+
+ fprintf(stderr, "\n");
+
+ while (line.ptr && line.ptr < p_end) {
+ fprintf(stderr, " %4u: %.*s\n", lineno, PSTR(line));
+ fprintf(stderr, " ");
+ for (size_t i = 0; i < line.len+1; i++) {
+ char *p = line.ptr + i;
+ fprintf(stderr, "%c", p >= p_start && p < p_end ? '^' : ' ');
+ }
+ fprintf(stderr, "\n");
+
+ line = str_walk(&iter, S("\n"));
+ lineno++;
+ }
+
+ exit(EXIT_FAILURE);
+}
+
+void source_free(struct source *src)
+{
+ free(src->contents.ptr);
+ for (size_t i = 0; i < src->strings.len; i++)
+ free(src->strings.ptr[i].ptr);
+ free(src->strings.ptr);
+}