From 8f6f28c8d3fd6fb85439add3e812edeb5a887999 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Mon, 14 Dec 2015 23:43:22 -0600 Subject: [PATCH] Make it easier to use jq with shebangs (fix #1044) Allow a continuation on a comment immediately after a shebang to make this traditional hack possible: #!/bin/sh # this next line is ignored by jq \ exec jq -f "$0" "$@" # jq code follows But continue only on the first line following a shebang, and only if it's a comment. --- src/main.c | 17 ++++++++++++++++- tests/jq-f-test.sh | 4 ++++ tests/shtest | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 tests/jq-f-test.sh diff --git a/src/main.c b/src/main.c index 8ffa0dbb02..eb9d35cf1f 100644 --- a/src/main.c +++ b/src/main.c @@ -129,6 +129,21 @@ enum { }; static int options = 0; +static const char *skip_shebang(const char *p) { + if (strncmp(p, "#!", sizeof("#!") - 1) != 0) + return p; + const char *n = strchr(p, '\n'); + if (n == NULL || n[1] != '#') + return p; + n = strchr(n + 1, '\n'); + if (n == NULL || n[1] == '#' || n[1] == '\0' || n[-1] != '\\' || n[-2] == '\\') + return p; + n = strchr(n + 1, '\n'); + if (n == NULL) + return p; + return n+1; +} + static int process(jq_state *jq, jv value, int flags, int dumpopts) { int ret = 14; // No valid results && -e -> exit(4) jq_start(jq, value, flags); @@ -493,7 +508,7 @@ int main(int argc, char* argv[]) { goto out; } jq_set_attr(jq, jv_string("PROGRAM_ORIGIN"), jq_realpath(jv_string(dirname(program_origin)))); - compiled = jq_compile_args(jq, jv_string_value(data), jv_copy(program_arguments)); + compiled = jq_compile_args(jq, skip_shebang(jv_string_value(data)), jv_copy(program_arguments)); free(program_origin); jv_free(data); } else { diff --git a/tests/jq-f-test.sh b/tests/jq-f-test.sh new file mode 100755 index 0000000000..a9c2fcf36d --- /dev/null +++ b/tests/jq-f-test.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# this next line is ignored by jq, which otherwise does not continue comments \ +exec jq -nef "$0" "$@" +true diff --git a/tests/shtest b/tests/shtest index 1a95613017..89ae61772c 100755 --- a/tests/shtest +++ b/tests/shtest @@ -2,6 +2,8 @@ . "${0%/*}/setup" +PATH=$JQBASEDIR:$PATH $JQBASEDIR/tests/jq-f-test.sh > /dev/null + if [ -f "$JQBASEDIR/.libs/libinject_errors.so" ]; then # Do some simple error injection tests to check that we're handling # I/O errors correctly.