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:
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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: "`.`"
|
||||
|
15
execute.c
15
execute.c
@ -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());
|
||||
}
|
||||
|
@ -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
15
main.c
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user