mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Make C-coded built-ins take jq_state *
argument
This commit is contained in:
106
builtin.c
106
builtin.c
@ -30,7 +30,7 @@ static jv type_error2(jv bad1, jv bad2, const char* msg) {
|
||||
return err;
|
||||
}
|
||||
|
||||
static jv f_plus(jv input, jv a, jv b) {
|
||||
static jv f_plus(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
if (jv_get_kind(a) == JV_KIND_NULL) {
|
||||
jv_free(a);
|
||||
@ -53,7 +53,7 @@ static jv f_plus(jv input, jv a, jv b) {
|
||||
}
|
||||
|
||||
#define LIBM_DD(name) \
|
||||
static jv f_ ## name(jv input) { \
|
||||
static jv f_ ## name(jq_state *jq, jv input) { \
|
||||
if (jv_get_kind(input) != JV_KIND_NUMBER) { \
|
||||
return type_error(input, "number required"); \
|
||||
} \
|
||||
@ -64,7 +64,7 @@ static jv f_ ## name(jv input) { \
|
||||
#include "libm.h"
|
||||
#undef LIBM_DD
|
||||
|
||||
static jv f_negate(jv input) {
|
||||
static jv f_negate(jq_state *jq, jv input) {
|
||||
if (jv_get_kind(input) != JV_KIND_NUMBER) {
|
||||
return type_error(input, "cannot be negated");
|
||||
}
|
||||
@ -73,7 +73,7 @@ static jv f_negate(jv input) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static jv f_startswith(jv a, jv b) {
|
||||
static jv f_startswith(jq_state *jq, jv a, jv b) {
|
||||
int alen = jv_string_length_bytes(jv_copy(a));
|
||||
int blen = jv_string_length_bytes(jv_copy(b));
|
||||
jv ret;
|
||||
@ -87,7 +87,7 @@ static jv f_startswith(jv a, jv b) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static jv f_endswith(jv a, jv b) {
|
||||
static jv f_endswith(jq_state *jq, jv a, jv b) {
|
||||
const char *astr = jv_string_value(a);
|
||||
const char *bstr = jv_string_value(b);
|
||||
size_t alen = jv_string_length_bytes(jv_copy(a));
|
||||
@ -104,8 +104,8 @@ static jv f_endswith(jv a, jv b) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static jv f_ltrimstr(jv input, jv left) {
|
||||
if (jv_get_kind(f_startswith(jv_copy(input), jv_copy(left))) != JV_KIND_TRUE) {
|
||||
static jv f_ltrimstr(jq_state *jq, jv input, jv left) {
|
||||
if (jv_get_kind(f_startswith(jq, jv_copy(input), jv_copy(left))) != JV_KIND_TRUE) {
|
||||
jv_free(left);
|
||||
return input;
|
||||
}
|
||||
@ -120,8 +120,8 @@ static jv f_ltrimstr(jv input, jv left) {
|
||||
return res;
|
||||
}
|
||||
|
||||
static jv f_rtrimstr(jv input, jv right) {
|
||||
if (jv_get_kind(f_endswith(jv_copy(input), jv_copy(right))) == JV_KIND_TRUE) {
|
||||
static jv f_rtrimstr(jq_state *jq, jv input, jv right) {
|
||||
if (jv_get_kind(f_endswith(jq, jv_copy(input), jv_copy(right))) == JV_KIND_TRUE) {
|
||||
jv res = jv_string_sized(jv_string_value(input),
|
||||
jv_string_length_bytes(jv_copy(input)) - jv_string_length_bytes(right));
|
||||
jv_free(input);
|
||||
@ -131,7 +131,7 @@ static jv f_rtrimstr(jv input, jv right) {
|
||||
return input;
|
||||
}
|
||||
|
||||
static jv f_minus(jv input, jv a, jv b) {
|
||||
static jv f_minus(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
||||
return jv_number(jv_number_value(a) - jv_number_value(b));
|
||||
@ -157,7 +157,7 @@ static jv f_minus(jv input, jv a, jv b) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_multiply(jv input, jv a, jv b) {
|
||||
static jv f_multiply(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_kind ak = jv_get_kind(a);
|
||||
jv_kind bk = jv_get_kind(b);
|
||||
jv_free(input);
|
||||
@ -191,7 +191,7 @@ static jv f_multiply(jv input, jv a, jv b) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_divide(jv input, jv a, jv b) {
|
||||
static jv f_divide(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
||||
return jv_number(jv_number_value(a) / jv_number_value(b));
|
||||
@ -202,7 +202,7 @@ static jv f_divide(jv input, jv a, jv b) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_mod(jv input, jv a, jv b) {
|
||||
static jv f_mod(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
||||
return jv_number((intmax_t)jv_number_value(a) % (intmax_t)jv_number_value(b));
|
||||
@ -211,12 +211,12 @@ static jv f_mod(jv input, jv a, jv b) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_equal(jv input, jv a, jv b) {
|
||||
static jv f_equal(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
return jv_bool(jv_equal(a, b));
|
||||
}
|
||||
|
||||
static jv f_notequal(jv input, jv a, jv b) {
|
||||
static jv f_notequal(jq_state *jq, jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
return jv_bool(!jv_equal(a, b));
|
||||
}
|
||||
@ -237,23 +237,23 @@ static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) {
|
||||
(op == CMP_OP_GREATER && r > 0));
|
||||
}
|
||||
|
||||
static jv f_less(jv input, jv a, jv b) {
|
||||
static jv f_less(jq_state *jq, jv input, jv a, jv b) {
|
||||
return order_cmp(input, a, b, CMP_OP_LESS);
|
||||
}
|
||||
|
||||
static jv f_greater(jv input, jv a, jv b) {
|
||||
static jv f_greater(jq_state *jq, jv input, jv a, jv b) {
|
||||
return order_cmp(input, a, b, CMP_OP_GREATER);
|
||||
}
|
||||
|
||||
static jv f_lesseq(jv input, jv a, jv b) {
|
||||
static jv f_lesseq(jq_state *jq, jv input, jv a, jv b) {
|
||||
return order_cmp(input, a, b, CMP_OP_LESSEQ);
|
||||
}
|
||||
|
||||
static jv f_greatereq(jv input, jv a, jv b) {
|
||||
static jv f_greatereq(jq_state *jq, jv input, jv a, jv b) {
|
||||
return order_cmp(input, a, b, CMP_OP_GREATEREQ);
|
||||
}
|
||||
|
||||
static jv f_contains(jv a, jv b) {
|
||||
static jv f_contains(jq_state *jq, jv a, jv b) {
|
||||
if (jv_get_kind(a) == jv_get_kind(b)) {
|
||||
return jv_bool(jv_contains(a, b));
|
||||
} else {
|
||||
@ -261,11 +261,11 @@ static jv f_contains(jv a, jv b) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_dump(jv input) {
|
||||
static jv f_dump(jq_state *jq, jv input) {
|
||||
return jv_dump_string(input, 0);
|
||||
}
|
||||
|
||||
static jv f_json_parse(jv input) {
|
||||
static jv f_json_parse(jq_state *jq, jv input) {
|
||||
if (jv_get_kind(input) != JV_KIND_STRING)
|
||||
return type_error(input, "only strings can be parsed");
|
||||
jv res = jv_parse_sized(jv_string_value(input),
|
||||
@ -274,7 +274,7 @@ static jv f_json_parse(jv input) {
|
||||
return res;
|
||||
}
|
||||
|
||||
static jv f_tonumber(jv input) {
|
||||
static jv f_tonumber(jq_state *jq, jv input) {
|
||||
if (jv_get_kind(input) == JV_KIND_NUMBER) {
|
||||
return input;
|
||||
}
|
||||
@ -288,7 +288,7 @@ static jv f_tonumber(jv input) {
|
||||
return type_error(input, "cannot be parsed as a number");
|
||||
}
|
||||
|
||||
static jv f_length(jv input) {
|
||||
static jv f_length(jq_state *jq, jv input) {
|
||||
if (jv_get_kind(input) == JV_KIND_ARRAY) {
|
||||
return jv_number(jv_array_length(input));
|
||||
} else if (jv_get_kind(input) == JV_KIND_OBJECT) {
|
||||
@ -305,7 +305,7 @@ static jv f_length(jv input) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_tostring(jv input) {
|
||||
static jv f_tostring(jq_state *jq, jv input) {
|
||||
if (jv_get_kind(input) == JV_KIND_STRING) {
|
||||
return input;
|
||||
} else {
|
||||
@ -345,7 +345,7 @@ static jv escape_string(jv input, const char* escapings) {
|
||||
|
||||
}
|
||||
|
||||
static jv f_format(jv input, jv fmt) {
|
||||
static jv f_format(jq_state *jq, jv input, jv fmt) {
|
||||
if (jv_get_kind(fmt) != JV_KIND_STRING) {
|
||||
jv_free(input);
|
||||
return type_error(fmt, "is not a valid format");
|
||||
@ -356,7 +356,7 @@ static jv f_format(jv input, jv fmt) {
|
||||
return jv_dump_string(input, 0);
|
||||
} else if (!strcmp(fmt_s, "text")) {
|
||||
jv_free(fmt);
|
||||
return f_tostring(input);
|
||||
return f_tostring(jq, input);
|
||||
} else if (!strcmp(fmt_s, "csv")) {
|
||||
jv_free(fmt);
|
||||
if (jv_get_kind(input) != JV_KIND_ARRAY)
|
||||
@ -397,10 +397,10 @@ static jv f_format(jv input, jv fmt) {
|
||||
return line;
|
||||
} else if (!strcmp(fmt_s, "html")) {
|
||||
jv_free(fmt);
|
||||
return escape_string(f_tostring(input), "&&\0<<\0>>\0''\0\""\0");
|
||||
return escape_string(f_tostring(jq, input), "&&\0<<\0>>\0''\0\""\0");
|
||||
} else if (!strcmp(fmt_s, "uri")) {
|
||||
jv_free(fmt);
|
||||
input = f_tostring(input);
|
||||
input = f_tostring(jq, input);
|
||||
|
||||
int unreserved[128] = {0};
|
||||
const char* p = CHARS_ALPHANUM "-_.!~*'()";
|
||||
@ -451,7 +451,7 @@ static jv f_format(jv input, jv fmt) {
|
||||
return line;
|
||||
} else if (!strcmp(fmt_s, "base64")) {
|
||||
jv_free(fmt);
|
||||
input = f_tostring(input);
|
||||
input = f_tostring(jq, input);
|
||||
jv line = jv_string("");
|
||||
const char b64[64 + 1] = CHARS_ALPHANUM "+/";
|
||||
const unsigned char* data = (const unsigned char*)jv_string_value(input);
|
||||
@ -479,7 +479,7 @@ static jv f_format(jv input, jv fmt) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_keys(jv input) {
|
||||
static jv f_keys(jq_state *jq, jv input) {
|
||||
if (jv_get_kind(input) == JV_KIND_OBJECT || jv_get_kind(input) == JV_KIND_ARRAY) {
|
||||
return jv_keys(input);
|
||||
} else {
|
||||
@ -487,7 +487,7 @@ static jv f_keys(jv input) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_sort(jv input){
|
||||
static jv f_sort(jq_state *jq, jv input){
|
||||
if (jv_get_kind(input) == JV_KIND_ARRAY) {
|
||||
return jv_sort(input, jv_copy(input));
|
||||
} else {
|
||||
@ -495,7 +495,7 @@ static jv f_sort(jv input){
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_sort_by_impl(jv input, jv keys) {
|
||||
static jv f_sort_by_impl(jq_state *jq, jv input, jv keys) {
|
||||
if (jv_get_kind(input) == JV_KIND_ARRAY &&
|
||||
jv_get_kind(keys) == JV_KIND_ARRAY &&
|
||||
jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
|
||||
@ -505,7 +505,7 @@ static jv f_sort_by_impl(jv input, jv keys) {
|
||||
}
|
||||
}
|
||||
|
||||
static jv f_group_by_impl(jv input, jv keys) {
|
||||
static jv f_group_by_impl(jq_state *jq, jv input, jv keys) {
|
||||
if (jv_get_kind(input) == JV_KIND_ARRAY &&
|
||||
jv_get_kind(keys) == JV_KIND_ARRAY &&
|
||||
jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
|
||||
@ -532,7 +532,7 @@ static int f_match_name_iter(const UChar* name, const UChar *name_end, int ngrou
|
||||
}
|
||||
|
||||
|
||||
static jv f_match(jv input, jv regex, jv modifiers, jv testmode) {
|
||||
static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
|
||||
int test = jv_equal(testmode, jv_true());
|
||||
jv result;
|
||||
int onigret;
|
||||
@ -756,30 +756,30 @@ static jv minmax_by(jv values, jv keys, int is_min) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static jv f_min(jv x) {
|
||||
static jv f_min(jq_state *jq, jv x) {
|
||||
return minmax_by(x, jv_copy(x), 1);
|
||||
}
|
||||
|
||||
static jv f_max(jv x) {
|
||||
static jv f_max(jq_state *jq, jv x) {
|
||||
return minmax_by(x, jv_copy(x), 0);
|
||||
}
|
||||
|
||||
static jv f_min_by_impl(jv x, jv y) {
|
||||
static jv f_min_by_impl(jq_state *jq, jv x, jv y) {
|
||||
return minmax_by(x, y, 1);
|
||||
}
|
||||
|
||||
static jv f_max_by_impl(jv x, jv y) {
|
||||
static jv f_max_by_impl(jq_state *jq, jv x, jv y) {
|
||||
return minmax_by(x, y, 0);
|
||||
}
|
||||
|
||||
|
||||
static jv f_type(jv input) {
|
||||
static jv f_type(jq_state *jq, jv input) {
|
||||
jv out = jv_string(jv_kind_name(jv_get_kind(input)));
|
||||
jv_free(input);
|
||||
return out;
|
||||
}
|
||||
|
||||
static jv f_error(jv input, jv msg) {
|
||||
static jv f_error(jq_state *jq, jv input, jv msg) {
|
||||
jv_free(input);
|
||||
return jv_invalid_with_msg(msg);
|
||||
}
|
||||
@ -789,7 +789,7 @@ static jv f_error(jv input, jv msg) {
|
||||
extern const char **environ;
|
||||
#endif
|
||||
|
||||
static jv f_env(jv input) {
|
||||
static jv f_env(jq_state *jq, jv input) {
|
||||
jv_free(input);
|
||||
jv env = jv_object();
|
||||
const char *var, *val;
|
||||
@ -804,6 +804,14 @@ static jv f_env(jv input) {
|
||||
return env;
|
||||
}
|
||||
|
||||
static jv f_string_split(jq_state *jq, jv a, jv b) { return jv_string_split(a, b); }
|
||||
static jv f_string_explode(jq_state *jq, jv a) { return jv_string_explode(a); }
|
||||
static jv f_string_implode(jq_state *jq, jv a) { return jv_string_implode(a); }
|
||||
static jv f_setpath(jq_state *jq, jv a, jv b, jv c) { return jv_setpath(a, b, c); }
|
||||
static jv f_getpath(jq_state *jq, jv a, jv b) { return jv_getpath(a, b); }
|
||||
static jv f_delpaths(jq_state *jq, jv a, jv b) { return jv_delpaths(a, b); }
|
||||
static jv f_has(jq_state *jq, jv a, jv b) { return jv_has(a, b); }
|
||||
|
||||
#define LIBM_DD(name) \
|
||||
{(cfunction_ptr)f_ ## name, "_" #name, 1},
|
||||
|
||||
@ -824,13 +832,13 @@ static const struct cfunction function_list[] = {
|
||||
{(cfunction_ptr)f_endswith, "endswith", 2},
|
||||
{(cfunction_ptr)f_ltrimstr, "ltrimstr", 2},
|
||||
{(cfunction_ptr)f_rtrimstr, "rtrimstr", 2},
|
||||
{(cfunction_ptr)jv_string_split, "split", 2},
|
||||
{(cfunction_ptr)jv_string_explode, "explode", 1},
|
||||
{(cfunction_ptr)jv_string_implode, "implode", 1},
|
||||
{(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking
|
||||
{(cfunction_ptr)jv_getpath, "getpath", 2},
|
||||
{(cfunction_ptr)jv_delpaths, "delpaths", 2},
|
||||
{(cfunction_ptr)jv_has, "has", 2},
|
||||
{(cfunction_ptr)f_string_split, "split", 2},
|
||||
{(cfunction_ptr)f_string_explode, "explode", 1},
|
||||
{(cfunction_ptr)f_string_implode, "implode", 1},
|
||||
{(cfunction_ptr)f_setpath, "setpath", 3}, // FIXME typechecking
|
||||
{(cfunction_ptr)f_getpath, "getpath", 2},
|
||||
{(cfunction_ptr)f_delpaths, "delpaths", 2},
|
||||
{(cfunction_ptr)f_has, "has", 2},
|
||||
{(cfunction_ptr)f_equal, "_equal", 3},
|
||||
{(cfunction_ptr)f_notequal, "_notequal", 3},
|
||||
{(cfunction_ptr)f_less, "_less", 3},
|
||||
|
20
execute.c
20
execute.c
@ -650,17 +650,17 @@ jv jq_next(jq_state *jq) {
|
||||
in[i] = stack_pop(jq);
|
||||
}
|
||||
struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++];
|
||||
typedef jv (*func_1)(jv);
|
||||
typedef jv (*func_2)(jv,jv);
|
||||
typedef jv (*func_3)(jv,jv,jv);
|
||||
typedef jv (*func_4)(jv,jv,jv,jv);
|
||||
typedef jv (*func_5)(jv,jv,jv,jv,jv);
|
||||
typedef jv (*func_1)(jq_state*,jv);
|
||||
typedef jv (*func_2)(jq_state*,jv,jv);
|
||||
typedef jv (*func_3)(jq_state*,jv,jv,jv);
|
||||
typedef jv (*func_4)(jq_state*,jv,jv,jv,jv);
|
||||
typedef jv (*func_5)(jq_state*,jv,jv,jv,jv,jv);
|
||||
switch (function->nargs) {
|
||||
case 1: top = ((func_1)function->fptr)(in[0]); break;
|
||||
case 2: top = ((func_2)function->fptr)(in[0], in[1]); break;
|
||||
case 3: top = ((func_3)function->fptr)(in[0], in[1], in[2]); break;
|
||||
case 4: top = ((func_4)function->fptr)(in[0], in[1], in[2], in[3]); break;
|
||||
case 5: top = ((func_5)function->fptr)(in[0], in[1], in[2], in[3], in[4]); break;
|
||||
case 1: top = ((func_1)function->fptr)(jq, in[0]); break;
|
||||
case 2: top = ((func_2)function->fptr)(jq, in[0], in[1]); break;
|
||||
case 3: top = ((func_3)function->fptr)(jq, in[0], in[1], in[2]); break;
|
||||
case 4: top = ((func_4)function->fptr)(jq, in[0], in[1], in[2], in[3]); break;
|
||||
case 5: top = ((func_5)function->fptr)(jq, in[0], in[1], in[2], in[3], in[4]); break;
|
||||
// FIXME: a) up to 7 arguments (input + 6), b) should assert
|
||||
// because the compiler should not generate this error.
|
||||
default: return jv_invalid_with_msg(jv_string("Function takes too many arguments"));
|
||||
|
Reference in New Issue
Block a user