diff options
author | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-09-18 17:44:43 +0100 |
---|---|---|
committer | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-09-18 17:44:43 +0100 |
commit | a4eea165bbab6d13f89b59707e835d58b7014a66 (patch) | |
tree | b99ee5dde8540f8dbe5de3d87b99e04ac4dd2673 /locfile.h | |
parent | 25cbab056b1f73e96b636c88779a92400d92dc15 (diff) |
Move everything around - delete old Haskell code, clean up build.
Diffstat (limited to 'locfile.h')
-rw-r--r-- | locfile.h | 78 |
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 |