]> granicus.if.org Git - jq/commitdiff
Make it easier to use jq with shebangs (fix #1044)
authorNicolas Williams <nico@cryptonector.com>
Tue, 15 Dec 2015 05:43:22 +0000 (23:43 -0600)
committerDavid Tolnay <dtolnay@gmail.com>
Tue, 15 Dec 2015 06:08:17 +0000 (22:08 -0800)
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
tests/jq-f-test.sh [new file with mode: 0755]
tests/shtest

index 8ffa0dbb021d58a29f46e8bf2c0e50cdb2206d96..eb9d35cf1fad91923b50ec154c77c3f2cbbfd41d 100644 (file)
@@ -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 (executable)
index 0000000..a9c2fcf
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+# this next line is ignored by jq, which otherwise does not continue comments \
+exec jq -nef "$0" "$@"
+true
index 1a9561301794ac068172fc6f826ef0478fd49a25..89ae61772cc13d4766c92de2201eadca72cc37cd 100755 (executable)
@@ -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.