diff options
author | Assaf Gordon <assafgordon@gmail.com> | 2015-04-17 16:08:10 -0400 |
---|---|---|
committer | Nicolas Williams <nico@cryptonector.com> | 2015-05-21 00:49:32 -0500 |
commit | d1cb8ee0ad3ddf03a37394bfa899cfd3ddd007c5 (patch) | |
tree | e06b0125148eea42b7881c380b6bcfb05c3b102f | |
parent | c7f063188f50ddf3271828244c5831a30f72a667 (diff) |
Add filename/line functions to jq (fix #753)
This adds `input_filename` and `input_line_number` built-in functions
for use in, for example, `error` messages.
Example:
$ printf '{"a":1}\n{"a":2}\n' > 4.json
$ printf '{"a":"hello"}\n' > 5.json
$ ./jq '{ "file":input_filename, "line":input_line_number, "value":.a }' 4.json 5.json
{
"file": "4.json",
"line": 1,
"value": 1
}
{
"file": "4.json",
"line": 2,
"value": 2
}
{
"file": "5.json",
"line": 1,
"value": "hello"
}
-rw-r--r-- | builtin.c | 8 | ||||
-rw-r--r-- | docs/content/3.manual/manual.yml | 11 | ||||
-rw-r--r-- | jq.h | 2 | ||||
-rw-r--r-- | tests/all.test | 9 | ||||
-rw-r--r-- | util.c | 23 |
5 files changed, 53 insertions, 0 deletions
@@ -1126,6 +1126,12 @@ static jv f_now(jq_state *jq, jv a) { } #endif +static jv f_current_filename(jq_state *jq) { + return jq_util_input_get_current_filename(jq); +} +static jv f_current_line(jq_state *jq) { + return jq_util_input_get_current_line(jq); +} #define LIBM_DD(name) \ {(cfunction_ptr)f_ ## name, "_" #name, 1}, @@ -1188,6 +1194,8 @@ static const struct cfunction function_list[] = { {(cfunction_ptr)f_mktime, "mktime", 1}, {(cfunction_ptr)f_gmtime, "gmtime", 1}, {(cfunction_ptr)f_now, "now", 1}, + {(cfunction_ptr)f_current_filename, "input_filename", 1}, + {(cfunction_ptr)f_current_line, "input_line_number", 1}, }; #undef LIBM_DD diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 39f69fe1..d55df30f 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -2413,6 +2413,17 @@ sections: `["DEBUG:", <input-value>]` and prints that and a newline on stderr, compactly. This may change in the future. + - title: "`input_filename`" + body: | + + Returns the name of the file whose input is currently being + filtered. + + - title: "`input_line_number`" + body: | + + Returns the line number of the input currently being filtered. + - title: Assignment body: | @@ -47,5 +47,7 @@ int jq_util_input_errors(jq_util_input_state); jv jq_util_input_next_input(jq_util_input_state); jv jq_util_input_next_input_cb(jq_state *, void *); jv jq_util_input_get_position(jq_state*); +jv jq_util_input_get_current_filename(jq_state*); +jv jq_util_input_get_current_line(jq_state*); #endif /* !JQ_H */ diff --git a/tests/all.test b/tests/all.test index 106afaa4..5a87398b 100644 --- a/tests/all.test +++ b/tests/all.test @@ -1173,3 +1173,12 @@ import "test_bind_order" as check; check::check null true +try input_filename catch . +null +"Unknown input filename" + +try input_line_number catch . +null +"Unknown input line number" + + @@ -341,6 +341,29 @@ jv jq_util_input_get_position(jq_state *jq) { return v; } +jv jq_util_input_get_current_filename(jq_state* jq) { + jq_input_cb cb=NULL; + void *cb_data=NULL; + jq_get_input_cb(jq, &cb, &cb_data); + if (cb != jq_util_input_next_input_cb) + return jv_invalid_with_msg(jv_string("Unknown input filename")); + jq_util_input_state s = (jq_util_input_state)cb_data; + jv v = jv_copy(s->current_filename); + return v; +} + +jv jq_util_input_get_current_line(jq_state* jq) { + jq_input_cb cb=NULL; + void *cb_data=NULL; + jq_get_input_cb(jq, &cb, &cb_data); + if (cb != jq_util_input_next_input_cb) + return jv_invalid_with_msg(jv_string("Unknown input line number")); + jq_util_input_state s = (jq_util_input_state)cb_data; + jv v = jv_number(s->current_line); + return v; +} + + // Blocks to read one more input from stdin and/or given files // When slurping, it returns just one value jv jq_util_input_next_input(jq_util_input_state state) { |