summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssaf Gordon <assafgordon@gmail.com>2015-04-17 16:08:10 -0400
committerNicolas Williams <nico@cryptonector.com>2015-05-21 00:49:32 -0500
commitd1cb8ee0ad3ddf03a37394bfa899cfd3ddd007c5 (patch)
treee06b0125148eea42b7881c380b6bcfb05c3b102f
parentc7f063188f50ddf3271828244c5831a30f72a667 (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.c8
-rw-r--r--docs/content/3.manual/manual.yml11
-rw-r--r--jq.h2
-rw-r--r--tests/all.test9
-rw-r--r--util.c23
5 files changed, 53 insertions, 0 deletions
diff --git a/builtin.c b/builtin.c
index c022416a..4747f618 100644
--- a/builtin.c
+++ b/builtin.c
@@ -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: |
diff --git a/jq.h b/jq.h
index 99e248ab..2c5ef168 100644
--- a/jq.h
+++ b/jq.h
@@ -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"
+
+
diff --git a/util.c b/util.c
index f6033b73..c8dd4f6d 100644
--- a/util.c
+++ b/util.c
@@ -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) {