summaryrefslogtreecommitdiffstats
path: root/locfile.h
diff options
context:
space:
mode:
authorStephen Dolan <mu@netsoc.tcd.ie>2012-09-18 17:44:43 +0100
committerStephen Dolan <mu@netsoc.tcd.ie>2012-09-18 17:44:43 +0100
commita4eea165bbab6d13f89b59707e835d58b7014a66 (patch)
treeb99ee5dde8540f8dbe5de3d87b99e04ac4dd2673 /locfile.h
parent25cbab056b1f73e96b636c88779a92400d92dc15 (diff)
Move everything around - delete old Haskell code, clean up build.
Diffstat (limited to 'locfile.h')
-rw-r--r--locfile.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/locfile.h b/locfile.h
new file mode 100644
index 00000000..77b1aef1
--- /dev/null
+++ b/locfile.h
@@ -0,0 +1,78 @@
+#ifndef _LOCFILE_H
+#define _LOCFILE_H
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+typedef struct {
+ int start, end;
+} location;
+
+static const location UNKNOWN_LOCATION = {-1, -1};
+
+struct locfile {
+ const char* data;
+ int length;
+ int* linemap;
+ int nlines;
+};
+
+static void locfile_init(struct locfile* l, const char* data, int length) {
+ l->data = data;
+ l->length = length;
+ l->nlines = 1;
+ for (int i=0; i<length; i++) {
+ if (data[i] == '\n') l->nlines++;
+ }
+ l->linemap = malloc(sizeof(int) * (l->nlines + 1));
+ l->linemap[0] = 0;
+ int line = 1;
+ for (int i=0; i<length; i++) {
+ if (data[i] == '\n') {
+ l->linemap[line] = i;
+ line++;
+ }
+ }
+ l->linemap[l->nlines] = length;
+}
+
+static void locfile_free(struct locfile* l) {
+ free(l->linemap);
+}
+
+static int locfile_get_line(struct locfile* l, int pos) {
+ assert(pos < l->length);
+ int line = 0;
+ while (l->linemap[line+1] < pos) line++;
+ assert(line < l->nlines);
+ return line;
+}
+
+static int locfile_line_length(struct locfile* l, int line) {
+ assert(line < l->nlines);
+ return l->linemap[line+1] - l->linemap[line];
+}
+
+static void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) {
+ va_list fmtargs;
+ va_start(fmtargs, fmt);
+ vfprintf(stderr, fmt, fmtargs);
+ va_end(fmtargs);
+ fprintf(stderr, "\n");
+ if (loc.start == -1) {
+ fprintf(stderr, "<unknown location>\n");
+ return;
+ }
+ int startline = locfile_get_line(l, loc.start);
+ int offset = l->linemap[startline];
+ fprintf(stderr, "%.*s\n", locfile_line_length(l, startline), l->data + offset);
+ fprintf(stderr, "%*s", loc.start - offset, "");
+ for (int i = loc.start;
+ i < loc.end && i < offset + locfile_line_length(l, startline);
+ i++){
+ fprintf(stderr, "^");
+ }
+ fprintf(stderr, "\n");
+}
+
+#endif