From d8672e1b2a004c70e1a7a60e58f68ac5d29fe7dc Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Mon, 7 Jul 2014 22:49:46 -0500 Subject: [PATCH] Make C-coded built-ins take `jq_state *` argument --- builtin.c | 106 +++++++++++++++++++++++++++++------------------------- execute.c | 20 +++++------ 2 files changed, 67 insertions(+), 59 deletions(-) diff --git a/builtin.c b/builtin.c index 69a4139..219133a 100644 --- a/builtin.c +++ b/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}, diff --git a/execute.c b/execute.c index 7b8f8f8..03a40a2 100644 --- a/execute.c +++ b/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")); -- 2.40.0