diff options
author | Nicolas Williams <nico@cryptonector.com> | 2015-12-14 23:43:22 -0600 |
---|---|---|
committer | David Tolnay <dtolnay@gmail.com> | 2015-12-14 22:08:17 -0800 |
commit | 8f6f28c8d3fd6fb85439add3e812edeb5a887999 (patch) | |
tree | bafea41cdd81cfe35c8f18103a6616a69405e6c3 | |
parent | 856a4b2f3faf2d6312aad47599e102c8c48d1bdd (diff) |
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.
-rw-r--r-- | src/main.c | 17 | ||||
-rwxr-xr-x | tests/jq-f-test.sh | 4 | ||||
-rwxr-xr-x | tests/shtest | 2 |
3 files changed, 22 insertions, 1 deletions
@@ -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 00000000..a9c2fcf3 --- /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 1a956130..89ae6177 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. |