From 7fb5d8c9738b0c0adc10f2169947b21bce465d45 Mon Sep 17 00:00:00 2001 From: Brendan Macmillan Date: Mon, 27 May 2013 10:00:01 +1000 Subject: [PATCH 1/3] Hack bugfix for multiline off-by-one (locfile.c) --- locfile.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locfile.h b/locfile.h index 710cfbd1..c557b987 100644 --- a/locfile.h +++ b/locfile.h @@ -66,8 +66,8 @@ static void locfile_locate(struct locfile* l, location loc, const char* fmt, ... } 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, ""); + fprintf(stderr, "%.*s\n", locfile_line_length(l, startline)-(startline!=0), l->data + offset +(startline!=0)); + fprintf(stderr, "%*s", loc.start - offset -(startline!=0), ""); for (int i = loc.start; i < loc.end && i < offset + locfile_line_length(l, startline); i++){ From 40378a18f7c669036d05918aa4f499d434e2e196 Mon Sep 17 00:00:00 2001 From: Brendan Macmillan Date: Sun, 26 May 2013 12:42:04 +1000 Subject: [PATCH 2/3] locfile.h -> locfile.h + locfile.c clean up includes of a few files --- Makefile.am | 4 ++-- builtin.c | 1 + locfile.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ locfile.h | 64 ++++--------------------------------------------- main.c | 1 + 5 files changed, 76 insertions(+), 62 deletions(-) create mode 100644 locfile.c diff --git a/Makefile.am b/Makefile.am index 23e9d253..a4d5cd1b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ JQ_INCS = jq_parser.h builtin.h bytecode.h compile.h execute.h \ jv_parse.h jv_unicode.h locfile.h opcode.h opcode_list.h parser.y \ jv_utf8_tables.h lexer.l -JQ_SRC = opcode.c bytecode.c compile.c execute.c builtin.c jv.c \ +JQ_SRC = locfile.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c \ jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jv_alloc.c \ jq_test.c ${JQ_INCS} @@ -123,4 +123,4 @@ if ENABLE_DOCS # 'make clean' doesn't delete the manpage if it can't be rebuilt clean-local: rm -f jq.1 -endif \ No newline at end of file +endif diff --git a/builtin.c b/builtin.c index 071cb564..9b5daef6 100644 --- a/builtin.c +++ b/builtin.c @@ -1,3 +1,4 @@ +#include #include #include "builtin.h" #include "compile.h" diff --git a/locfile.c b/locfile.c new file mode 100644 index 00000000..1c73f327 --- /dev/null +++ b/locfile.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include "jv_alloc.h" +#include "locfile.h" + + +void locfile_init(struct locfile* l, const char* data, int length) { + l->data = data; + l->length = length; + l->nlines = 1; + for (int i=0; inlines++; + } + l->linemap = jv_mem_alloc(sizeof(int) * (l->nlines + 1)); + l->linemap[0] = 0; + int line = 1; + for (int i=0; ilinemap[line] = i; + line++; + } + } + l->linemap[l->nlines] = length; +} + +void locfile_free(struct locfile* l) { + jv_mem_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]; +} + +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, "\n"); + return; + } + int startline = locfile_get_line(l, loc.start); + int offset = l->linemap[startline]; + fprintf(stderr, "HERE1\n%.*s\n", locfile_line_length(l, startline)-(startline!=0), l->data + offset +(startline!=0)); // if not first line, this starts at the '\n' in l + fprintf(stderr, "HERE2\n%*s", loc.start - offset -(startline!=0), ""); // space padding. If not first line, offset is the '\n' at beginning of line, and one too many + /* ASIDE: because all this code is in locfile.h instead of locfile.c, it recompiles everything, and takes forever */ + /* I've separated it out, into locfile.h; removed static */ + /* Problem: a few files include locfile.h to get the *.h it includes... this seems bad to me */ + for (int i = loc.start; + i < loc.end && i < offset + locfile_line_length(l, startline); + i++){ + fprintf(stderr, "^"); + } + fprintf(stderr, "\n"); +} diff --git a/locfile.h b/locfile.h index c557b987..35907974 100644 --- a/locfile.h +++ b/locfile.h @@ -1,10 +1,6 @@ #ifndef _LOCFILE_H #define _LOCFILE_H -#include -#include -#include -#include -#include "jv_alloc.h" + typedef struct { int start, end; } location; @@ -18,62 +14,10 @@ struct locfile { 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; inlines++; - } - l->linemap = jv_mem_alloc(sizeof(int) * (l->nlines + 1)); - l->linemap[0] = 0; - int line = 1; - for (int i=0; ilinemap[line] = i; - line++; - } - } - l->linemap[l->nlines] = length; -} +void locfile_init(struct locfile* l, const char* data, int length); -static void locfile_free(struct locfile* l) { - jv_mem_free(l->linemap); -} +void locfile_free(struct locfile* l); -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, "\n"); - return; - } - int startline = locfile_get_line(l, loc.start); - int offset = l->linemap[startline]; - fprintf(stderr, "%.*s\n", locfile_line_length(l, startline)-(startline!=0), l->data + offset +(startline!=0)); - fprintf(stderr, "%*s", loc.start - offset -(startline!=0), ""); - for (int i = loc.start; - i < loc.end && i < offset + locfile_line_length(l, startline); - i++){ - fprintf(stderr, "^"); - } - fprintf(stderr, "\n"); -} +void locfile_locate(struct locfile* l, location loc, const char* fmt, ...); #endif diff --git a/main.c b/main.c index 1e951849..8321743c 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,4 @@ +#include #include #include #include From 8cfe11e4e25e2149aba68bb77335024cc84999a5 Mon Sep 17 00:00:00 2001 From: Brendan Macmillan Date: Tue, 28 May 2013 14:11:24 +1000 Subject: [PATCH 3/3] Bugfix multiline off-by-one (locfile.c) --- .gitignore | 2 ++ locfile.c | 21 +++++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index ba354c63..eab159d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ *.o *~ +.*.sw[a-p] +tags jq jq.1 diff --git a/locfile.c b/locfile.c index 1c73f327..f1f17d0f 100644 --- a/locfile.c +++ b/locfile.c @@ -18,11 +18,11 @@ void locfile_init(struct locfile* l, const char* data, int length) { int line = 1; for (int i=0; ilinemap[line] = i; + l->linemap[line] = i+1; // at start of line, not of \n line++; } } - l->linemap[l->nlines] = length; + l->linemap[l->nlines] = length+1; // virtual last \n } void locfile_free(struct locfile* l) { @@ -31,15 +31,15 @@ void locfile_free(struct locfile* l) { 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; + int line = 1; + while (l->linemap[line] <= pos) line++; // == if pos at start (before, never ==, because pos never on \n) + assert(line-1 < l->nlines); + return line-1; } static int locfile_line_length(struct locfile* l, int line) { assert(line < l->nlines); - return l->linemap[line+1] - l->linemap[line]; + return l->linemap[line+1] - l->linemap[line] -1; // -1 to omit \n } void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) { @@ -54,11 +54,8 @@ void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) { } int startline = locfile_get_line(l, loc.start); int offset = l->linemap[startline]; - fprintf(stderr, "HERE1\n%.*s\n", locfile_line_length(l, startline)-(startline!=0), l->data + offset +(startline!=0)); // if not first line, this starts at the '\n' in l - fprintf(stderr, "HERE2\n%*s", loc.start - offset -(startline!=0), ""); // space padding. If not first line, offset is the '\n' at beginning of line, and one too many - /* ASIDE: because all this code is in locfile.h instead of locfile.c, it recompiles everything, and takes forever */ - /* I've separated it out, into locfile.h; removed static */ - /* Problem: a few files include locfile.h to get the *.h it includes... this seems bad to me */ + 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++){