1
0
mirror of https://github.com/stedolan/jq.git synced 2024-05-11 05:55:39 +00:00

Add a --arg option to allow variables to be passed from the cmdline.

Closes #107
This commit is contained in:
Stephen Dolan
2013-05-06 14:21:00 +01:00
parent 48be23233a
commit 5be97463ec
7 changed files with 46 additions and 6 deletions

View File

@ -371,6 +371,12 @@ block gen_or(block a, block b) {
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),

View File

@ -40,6 +40,8 @@ block gen_condbranch(block iftrue, block iffalse);
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);

View File

@ -121,6 +121,12 @@ sections:
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: "`.`"

View File

@ -506,13 +506,22 @@ void jq_teardown(jq_state **jq) {
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);
}
@ -522,3 +531,7 @@ struct bytecode* jq_compile(const char* str) {
locfile_free(&locations);
return bc;
}
struct bytecode* jq_compile(const char* str) {
return jq_compile_args(str, jv_array());
}

View File

@ -3,8 +3,12 @@
#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};

15
main.c
View File

@ -154,6 +154,7 @@ int main(int argc, char* argv[]) {
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];
@ -184,6 +185,16 @@ int main(int argc, char* argv[]) {
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")) {
@ -214,10 +225,10 @@ int main(int argc, char* argv[]) {
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;

View File

@ -201,9 +201,7 @@ FuncDef Exp %prec ';' {
} |
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);
} |