gen_const(jv_false())))));
}
+block gen_var_binding(block var, const char* name, block body) {
+ return BLOCK(gen_op_simple(DUP), var,
+ block_bind(gen_op_var_unbound(STOREV, name),
+ body, OP_HAS_VARIABLE));
+}
+
block gen_cond(block cond, block iftrue, block iffalse) {
return BLOCK(gen_op_simple(DUP), cond,
gen_condbranch(BLOCK(gen_op_simple(POP), iftrue),
block gen_and(block a, block b);
block gen_or(block a, block b);
+block gen_var_binding(block var, const char* name, block body);
+
block gen_cond(block cond, block iftrue, block iffalse);
block gen_cbinding(const struct cfunction* functions, int nfunctions, block b);
formatted as a JSON string with quotes. This can be useful for
making jq filters talk to non-JSON-based systems.
+ * `--arg name value`:
+
+ This option passes a value to the jq program as a predefined
+ variable. If you run jq with `--arg foo bar`, then `$foo` is
+ available in the program and has the value `"bar"`.
+
- title: Basic filters
entries:
- title: "`.`"
jv_mem_free(old_jq);
}
-struct bytecode* jq_compile(const char* str) {
+struct bytecode* jq_compile_args(const char* str, jv args) {
+ assert(jv_get_kind(args) == JV_KIND_ARRAY);
struct locfile locations;
locfile_init(&locations, str, strlen(str));
block program;
struct bytecode* bc = 0;
int nerrors = jq_parse(&locations, &program);
if (nerrors == 0) {
+ for (int i=0; i<jv_array_length(jv_copy(args)); i++) {
+ jv arg = jv_array_get(jv_copy(args), i);
+ jv name = jv_object_get(jv_copy(arg), jv_string("name"));
+ jv value = jv_object_get(arg, jv_string("value"));
+ program = gen_var_binding(gen_const(value), jv_string_value(name), program);
+ jv_free(name);
+ }
+ jv_free(args);
program = builtins_bind(program);
nerrors = block_compile(program, &locations, &bc);
}
locfile_free(&locations);
return bc;
}
+
+struct bytecode* jq_compile(const char* str) {
+ return jq_compile_args(str, jv_array());
+}
#include "bytecode.h"
+
struct bytecode* jq_compile(const char* str);
+/* args must be an array of the form [{name:"foo", value:"thing"}, {name:"bar",value:3}] */
+struct bytecode* jq_compile_args(const char* str, jv args);
+
typedef struct jq_state jq_state;
enum {JQ_DEBUG_TRACE = 1};
ninput_files = 0;
int further_args_are_files = 0;
int jq_flags = 0;
+ jv program_arguments = jv_array();
for (int i=1; i<argc; i++) {
if (further_args_are_files) {
input_filenames[ninput_files++] = argv[i];
options |= PROVIDE_NULL;
} else if (isoption(argv[i], 'f', "from-file")) {
options |= FROM_FILE;
+ } else if (isoption(argv[i], 0, "arg")) {
+ if (i >= argc - 2) {
+ fprintf(stderr, "%s: --arg takes two parameters (e.g. -a varname value)\n", progname);
+ die();
+ }
+ jv arg = jv_object();
+ arg = jv_object_set(arg, jv_string("name"), jv_string(argv[i+1]));
+ arg = jv_object_set(arg, jv_string("value"), jv_string(argv[i+2]));
+ program_arguments = jv_array_append(program_arguments, arg);
+ i += 2; // skip the next two arguments
} else if (isoption(argv[i], 0, "debug-dump-disasm")) {
options |= DUMP_DISASM;
} else if (isoption(argv[i], 0, "debug-trace")) {
jv_free(data);
return 1;
}
- bc = jq_compile(jv_string_value(data));
+ bc = jq_compile_args(jv_string_value(data), program_arguments);
jv_free(data);
} else {
- bc = jq_compile(program);
+ bc = jq_compile_args(program, program_arguments);
}
if (!bc) return 1;
} |
Term "as" '$' IDENT '|' Exp {
- $$ = BLOCK(gen_op_simple(DUP), $1,
- block_bind(gen_op_var_unbound(STOREV, jv_string_value($4)),
- $6, OP_HAS_VARIABLE));
+ $$ = gen_var_binding($1, jv_string_value($4), $6);
jv_free($4);
} |