@ 261102.1

190226.22 · 141bb78e967f0d088b9fda134bb75e23405bd844

Fix regression on ~/.jq being a directory

reading declarations

Makefile.am

@@ -170,23 +170,19 @@ DOC_FILES = docs/content docs/public docs/templates docs/site.yml       \  EXTRA_DIST = $(DOC_FILES) $(man_MANS) $(TESTS) $(TEST_LOG_COMPILER)     \         jq.1.prebuilt jq.spec src/lexer.c src/lexer.h src/parser.c      \-        src/parser.h src/version.h src/builtin.jq                       \-        scripts/version tests/jq.test tests/modules/.jq                 \+        src/parser.h src/version.h src/builtin.jq scripts/version       \+        tests/base64.test tests/jq-f-test.sh tests/jq.test              \         tests/modules/a.jq tests/modules/b/b.jq tests/modules/c/c.jq    \         tests/modules/c/d.jq tests/modules/data.json                    \+        tests/modules/home1/.jq tests/modules/home2/.jq/g.jq            \         tests/modules/lib/jq/e/e.jq tests/modules/lib/jq/f.jq           \         tests/modules/syntaxerror/syntaxerror.jq                        \         tests/modules/test_bind_order.jq                                \         tests/modules/test_bind_order0.jq                               \         tests/modules/test_bind_order1.jq                               \         tests/modules/test_bind_order2.jq tests/onig.supp               \-        tests/onig.test tests/setup tests/torture/input0.json           \-        tests/optional.test tests/optionaltest                          \-        tests/utf8-truncate.jq tests/utf8test                           \-        tests/base64.test tests/base64test                              \-        tests/jq-f-test.sh tests/shtest--+        tests/onig.test tests/optional.test tests/setup                 \+        tests/torture/input0.json tests/utf8-truncate.jq  # README.md is expected in Github projects, good stuff in it, so we'll # distribute it and install it with the package in the doc directory.

src/linker.c

@@ -26,7 +26,8 @@ struct lib_loading_state {   block *defs;   uint64_t ct; };-static int load_library(jq_state *jq, jv lib_path, int is_data, int raw,+static int load_library(jq_state *jq, jv lib_path,+                        int is_data, int raw, int optional,                         const char *as, block *out_block,                         struct lib_loading_state *lib_state); @@ -279,7 +280,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block     if (is_data) {       // Can't reuse data libs because the wrong name is bound       block dep_def_block;-      nerrors += load_library(jq, resolved, is_data, raw, as_str, &dep_def_block, lib_state);+      nerrors += load_library(jq, resolved, is_data, raw, optional, as_str, &dep_def_block, lib_state);       if (nerrors == 0) {         // Bind as both $data::data and $data for backward compatibility vs common sense         bk = block_bind_library(dep_def_block, bk, OP_IS_CALL_PSEUDO, as_str);@@ -298,7 +299,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block         bk = block_bind_library(lib_state->defs[state_idx], bk, OP_IS_CALL_PSEUDO, as_str);       } else { // Not found.   Add it to the table before binding.         block dep_def_block = gen_noop();-        nerrors += load_library(jq, resolved, is_data, raw, as_str, &dep_def_block, lib_state);+        nerrors += load_library(jq, resolved, is_data, raw, optional, as_str, &dep_def_block, lib_state);         // resolved has been freed         if (nerrors == 0) {           // Bind the library to the program@@ -317,7 +318,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block  // Loads the library at lib_path into lib_state, putting the library's defs // into *out_block-static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, const char *as, block *out_block, struct lib_loading_state *lib_state) {+static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, int optional, const char *as, block *out_block, struct lib_loading_state *lib_state) {   int nerrors = 0;   struct locfile* src = NULL;   block program;@@ -328,12 +329,15 @@ static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, const c     data = jv_load_file(jv_string_value(lib_path), 1);   int state_idx;   if (!jv_is_valid(data)) {-    if (jv_invalid_has_msg(jv_copy(data)))-      data = jv_invalid_get_msg(data);-    else-      data = jv_string("unknown error");-    jq_report_error(jq, jv_string_fmt("jq: error loading data file %s: %s\n", jv_string_value(lib_path), jv_string_value(data)));-    nerrors++;+    program = gen_noop();+    if (!optional) {+      if (jv_invalid_has_msg(jv_copy(data)))+        data = jv_invalid_get_msg(data);+      else+        data = jv_string("unknown error");+      jq_report_error(jq, jv_string_fmt("jq: error loading data file %s: %s\n", jv_string_value(lib_path), jv_string_value(data)));+      nerrors++;+    }     goto out;   } else if (is_data) {     // import "foo" as $bar;@@ -342,6 +346,7 @@ static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, const c     // import "foo" as bar;     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);+    locfile_free(src);     if (nerrors == 0) {       char *lib_origin = strdup(jv_string_value(lib_path));       nerrors += process_dependencies(jq, jq_get_jq_origin(jq),@@ -356,10 +361,8 @@ static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, const c   lib_state->defs = jv_mem_realloc(lib_state->defs, lib_state->ct * sizeof(block));   lib_state->names[state_idx] = strdup(jv_string_value(lib_path));   lib_state->defs[state_idx] = program;-  *out_block = program;-  if (src)-    locfile_free(src); out:+  *out_block = program;   jv_free(lib_path);   jv_free(data);   return nerrors;

tests/modules/.jq

deleted file mode 100644@@ -1,5 +0,0 @@-def foo: "baz";-def f: "wat";-def f: "foo";-def g: "bar";-def fg: f+g;

tests/modules/home1/.jq

new file mode 100644@@ -0,0 +1,5 @@+def foo: "baz";+def f: "wat";+def f: "foo";+def g: "bar";+def fg: f+g;

tests/modules/home2/.jq/g.jq

new file mode 100644@@ -0,0 +1 @@+def g: 1;

tests/shtest

@@ -218,16 +218,21 @@ clean=true  # Check handling of ~/.jq; these can't move into jq_test.c yet because # they depend on $HOME-if [ "$(HOME="$mods" $VALGRIND $Q $JQ -nr fg)" != foobar ]; then+if [ "$(HOME="$mods/home1" $VALGRIND $Q $JQ -nr fg)" != foobar ]; then     echo "Bug #479 appears to be back" 1>&2     exit 1 fi -if [ $(HOME="$mods" $VALGRIND $Q $JQ --debug-dump-disasm -n fg | grep '^[a-z]' | wc -l) -gt 3 ]; then+if [ $(HOME="$mods/home1" $VALGRIND $Q $JQ --debug-dump-disasm -n fg | grep '^[a-z]' | wc -l) -ne 3 ]; then     echo "Binding too many defs into program" 1>&2     exit 1 fi +if ! HOME="$mods/home2" $VALGRIND $Q $JQ -n 'include "g"; empty'; then+    echo "Mishanding directory ~/.jq" 1>&2+    exit 1+fi+ cd "$JQBASEDIR" # so that relative library paths are guaranteed correct if ! $VALGRIND $Q $JQ -L ./tests/modules -ne 'import "test_bind_order" as check; check::check==true'; then     echo "Issue #817 regression?" 1>&2