1
0
mirror of https://github.com/stedolan/jq.git synced 2024-05-11 05:55:39 +00:00

Include filename and lineno in error messages

This commit is contained in:
Nicolas Williams
2015-03-29 19:12:23 -05:00
parent 7d6d4066dd
commit 1dcfc2f547
7 changed files with 27 additions and 18 deletions

View File

@@ -1441,7 +1441,7 @@ static const char* const jq_builtins[] = {
static int builtins_bind_one(jq_state *jq, block* bb, const char* code) {
struct locfile* src;
src = locfile_init(jq, code, strlen(code));
src = locfile_init(jq, "<builtin>", code, strlen(code));
block funcs;
int nerrors = jq_parse_library(src, &funcs);
if (nerrors == 0) {

View File

@@ -1008,7 +1008,7 @@ int jq_compile_args(jq_state *jq, const char* str, jv args) {
jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data);
assert(jv_get_kind(args) == JV_KIND_ARRAY);
struct locfile* locations;
locations = locfile_init(jq, str, strlen(str));
locations = locfile_init(jq, "<top-level>", str, strlen(str));
block program;
jq_reset(jq);
if (jq->bc) {

View File

@@ -30,8 +30,12 @@ static int skipline(const char* buf) {
return 0;
}
static int checkerrormsg(const char* buf) {
return strcmp(buf, "%%FAIL\n") == 0;
}
static int checkfail(const char* buf) {
return !strcmp(buf, "%%FAIL\n");
return strcmp(buf, "%%FAIL\n") == 0 || strcmp(buf, "%%FAIL IGNORE MSG\n") == 0;
}
struct err_data {
@@ -56,6 +60,7 @@ static void run_jq_tests(jv lib_dirs, FILE *testdata) {
int tests = 0, passed = 0, invalid = 0;
unsigned int lineno = 0;
int must_fail = 0;
int check_msg = 0;
jq_state *jq = NULL;
jq = jq_init();
@@ -70,6 +75,7 @@ static void run_jq_tests(jv lib_dirs, FILE *testdata) {
if (skipline(prog)) continue;
if (checkfail(prog)) {
must_fail = 1;
check_msg = checkerrormsg(prog);
jq_set_error_cb(jq, test_err_cb, &err_msg);
continue;
}
@@ -82,6 +88,7 @@ static void run_jq_tests(jv lib_dirs, FILE *testdata) {
if (must_fail) {
jq_set_error_cb(jq, NULL, NULL);
must_fail = 0;
check_msg = 0;
if (!fgets(buf, sizeof(buf), testdata)) { invalid++; break; }
lineno++;
if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
@@ -89,7 +96,7 @@ static void run_jq_tests(jv lib_dirs, FILE *testdata) {
printf("*** Test program compiled that should not have at line %u: %s\n", lineno, prog);
invalid++; continue;
}
if (strcmp(buf, err_msg.buf)) {
if (check_msg && strcmp(buf, err_msg.buf) != 0) {
printf("*** Erroneous test program failed with wrong message (%s) at line %u: %s\n", err_msg.buf, lineno, prog);
invalid++;
} else {

View File

@@ -276,7 +276,7 @@ static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, const c
program = gen_const_global(jv_copy(data), as);
} else {
// import "foo" as bar;
src = locfile_init(jq, jv_string_value(data), jv_string_length_bytes(jv_copy(data)));
src = locfile_init(jq, jv_string_value(lib_path), jv_string_value(data), jv_string_length_bytes(jv_copy(data)));
nerrors += jq_parse_library(src, &program);
if (nerrors == 0) {
char *lib_origin = strdup(jv_string_value(lib_path));
@@ -311,7 +311,7 @@ jv load_module_meta(jq_state *jq, jv mod_relpath) {
jv data = jv_load_file(jv_string_value(lib_path), 1);
if (jv_is_valid(data)) {
block program;
struct locfile* src = locfile_init(jq, jv_string_value(data), jv_string_length_bytes(jv_copy(data)));
struct locfile* src = locfile_init(jq, jv_string_value(lib_path), jv_string_value(data), jv_string_length_bytes(jv_copy(data)));
int nerrors = jq_parse_library(src, &program);
if (nerrors == 0) {
meta = block_module_meta(program);

View File

@@ -9,9 +9,10 @@
#include "locfile.h"
struct locfile* locfile_init(jq_state *jq, const char* data, int length) {
struct locfile* locfile_init(jq_state *jq, const char *fname, const char* data, int length) {
struct locfile* l = jv_mem_alloc(sizeof(struct locfile));
l->jq = jq;
l->fname = jv_string(fname);
l->data = jv_mem_alloc(length);
memcpy((char*)l->data,data,length);
l->length = length;
@@ -39,6 +40,7 @@ struct locfile* locfile_retain(struct locfile* l) {
}
void locfile_free(struct locfile* l) {
if (--(l->refct) == 0) {
jv_free(l->fname);
jv_mem_free(l->linemap);
jv_mem_free((char*)l->data);
jv_mem_free(l);
@@ -79,7 +81,8 @@ void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) {
jv_free(m1);
return;
}
jv m2 = jv_string_fmt("%s\n%.*s%*s", jv_string_value(m1),
jv m2 = jv_string_fmt("%s at %s, line %d:\n%.*s%*s", jv_string_value(m1),
jv_string_value(l->fname), startline + 1,
locfile_line_length(l, startline), l->data + offset,
loc.start - offset, "");
jv_free(m1);

View File

@@ -10,6 +10,7 @@ typedef struct {
static const location UNKNOWN_LOCATION = {-1, -1};
struct locfile {
jv fname;
const char* data;
int length;
int* linemap;
@@ -19,11 +20,9 @@ struct locfile {
int refct;
};
struct locfile* locfile_init(jq_state *jq, const char* data, int length);
struct locfile* locfile_retain(struct locfile* l);
void locfile_free(struct locfile* l);
void locfile_locate(struct locfile* l, location loc, const char* fmt, ...);
struct locfile* locfile_init(jq_state *, const char *, const char *, int);
struct locfile* locfile_retain(struct locfile *);
void locfile_free(struct locfile *);
void locfile_locate(struct locfile *, location, const char *, ...);
#endif

View File

@@ -257,7 +257,7 @@ null
%%FAIL
. as $foo | break $foo
jq: error: *label-foo/0 is not defined
jq: error: *label-foo/0 is not defined at <top-level>, line 1:
[.[]|[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]]
[1,2,3,4,5]
@@ -1153,13 +1153,13 @@ modulemeta
"c"
{"whatever":null,"deps":[{"as":"foo","is_data":false,"relpath":"a"},{"search":"./","as":"d","is_data":false,"relpath":"d"},{"search":"./","as":"d2","is_data":false,"relpath":"d"},{"search":"./../lib/jq","as":"e","is_data":false,"relpath":"e"},{"search":"./../lib/jq","as":"f","is_data":false,"relpath":"f"},{"as":"d","is_data":true,"relpath":"data"}]}
%%FAIL
%%FAIL IGNORE MSG
import "syntaxerror" as e; .
jq: error: syntax error, unexpected ';', expecting $end (Unix shell quoting issues?)
jq: error: syntax error, unexpected ';', expecting $end (Unix shell quoting issues?) at /home/nico/ws/jq/tests/modules/syntaxerror/syntaxerror.jq, line 1:
%%FAIL
%::wat
jq: error: syntax error, unexpected '%', expecting $end (Unix shell quoting issues?)
jq: error: syntax error, unexpected '%', expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
import "test_bind_order" as check; check::check
null