Declare cfunction.fptr as jv (*)() to avoid having to cast everywhere

You only need to specify the return type in a function pointer
declaration in C.

If you use () in the declaration, the function pointer can be called
with any arguments, and the type of the arguments is decided for each
function call based on the types of the arguments used for the call.
(To declare a function pointer for a function with no arguments, you use
`(void)'.)

Since all the cfunction structs have a  fptr  that points to a functions
that return jv, not void, we can we can just declare cfunction.fptr as
jv (*)()  and avoid having those annoying and technically not C-standard
compliant casts everywhere.
This commit is contained in:
Emanuele Torre authored and Nico Williams committed 2023-07-31 15:28:01 -05:00
1 parent f61f842ad0
commit 6716e23ae6
4 files changed
+81 -88

No files matched your search

+1 -2
View File
@@ -20,8 +20,7 @@ LIBJQ_SRC = src/builtin.c src/bytecode.c src/compile.c src/execute.c \
### C build options ### C build options
AM_CFLAGS = -Wextra -Wall -Wno-missing-field-initializers \ AM_CFLAGS = -Wextra -Wall -Wno-missing-field-initializers \
-Wno-unused-parameter -Wno-unused-function \ -Wno-unused-parameter -Wno-unused-function
-Wno-cast-function-type
if WIN32 if WIN32
AM_CFLAGS += -municode AM_CFLAGS += -municode
+74 -74
View File
@@ -1704,96 +1704,96 @@ static jv f_current_line(jq_state *jq, jv a) {
} }
#define LIBM_DD(name) \ #define LIBM_DD(name) \
{(cfunction_ptr)f_ ## name, #name, 1}, {f_ ## name, #name, 1},
#define LIBM_DD_NO(name) #define LIBM_DD_NO(name)
#define LIBM_DDD(name) \ #define LIBM_DDD(name) \
{(cfunction_ptr)f_ ## name, #name, 3}, {f_ ## name, #name, 3},
#define LIBM_DDD_NO(name) #define LIBM_DDD_NO(name)
#define LIBM_DDDD(name) \ #define LIBM_DDDD(name) \
{(cfunction_ptr)f_ ## name, #name, 4}, {f_ ## name, #name, 4},
#define LIBM_DDDD_NO(name) #define LIBM_DDDD_NO(name)
static const struct cfunction function_list[] = { static const struct cfunction function_list[] = {
#include "libm.h" #include "libm.h"
#ifdef HAVE_FREXP #ifdef HAVE_FREXP
{(cfunction_ptr)f_frexp,"frexp", 1}, {f_frexp,"frexp", 1},
#endif #endif
#ifdef HAVE_MODF #ifdef HAVE_MODF
{(cfunction_ptr)f_modf,"modf", 1}, {f_modf,"modf", 1},
#endif #endif
#ifdef HAVE_LGAMMA_R #ifdef HAVE_LGAMMA_R
{(cfunction_ptr)f_lgamma_r,"lgamma_r", 1}, {f_lgamma_r,"lgamma_r", 1},
#endif #endif
{(cfunction_ptr)f_plus, "_plus", 3}, {f_plus, "_plus", 3},
{(cfunction_ptr)f_negate, "_negate", 1}, {f_negate, "_negate", 1},
{(cfunction_ptr)f_minus, "_minus", 3}, {f_minus, "_minus", 3},
{(cfunction_ptr)f_multiply, "_multiply", 3}, {f_multiply, "_multiply", 3},
{(cfunction_ptr)f_divide, "_divide", 3}, {f_divide, "_divide", 3},
{(cfunction_ptr)f_mod, "_mod", 3}, {f_mod, "_mod", 3},
{(cfunction_ptr)f_dump, "tojson", 1}, {f_dump, "tojson", 1},
{(cfunction_ptr)f_json_parse, "fromjson", 1}, {f_json_parse, "fromjson", 1},
{(cfunction_ptr)f_tonumber, "tonumber", 1}, {f_tonumber, "tonumber", 1},
{(cfunction_ptr)f_tostring, "tostring", 1}, {f_tostring, "tostring", 1},
{(cfunction_ptr)f_keys, "keys", 1}, {f_keys, "keys", 1},
{(cfunction_ptr)f_keys_unsorted, "keys_unsorted", 1}, {f_keys_unsorted, "keys_unsorted", 1},
{(cfunction_ptr)f_startswith, "startswith", 2}, {f_startswith, "startswith", 2},
{(cfunction_ptr)f_endswith, "endswith", 2}, {f_endswith, "endswith", 2},
{(cfunction_ptr)f_ltrimstr, "ltrimstr", 2}, {f_ltrimstr, "ltrimstr", 2},
{(cfunction_ptr)f_rtrimstr, "rtrimstr", 2}, {f_rtrimstr, "rtrimstr", 2},
{(cfunction_ptr)f_string_split, "split", 2}, {f_string_split, "split", 2},
{(cfunction_ptr)f_string_explode, "explode", 1}, {f_string_explode, "explode", 1},
{(cfunction_ptr)f_string_implode, "implode", 1}, {f_string_implode, "implode", 1},
{(cfunction_ptr)f_string_indexes, "_strindices", 2}, {f_string_indexes, "_strindices", 2},
{(cfunction_ptr)f_setpath, "setpath", 3}, // FIXME typechecking {f_setpath, "setpath", 3}, // FIXME typechecking
{(cfunction_ptr)f_getpath, "getpath", 2}, {f_getpath, "getpath", 2},
{(cfunction_ptr)f_delpaths, "delpaths", 2}, {f_delpaths, "delpaths", 2},
{(cfunction_ptr)f_has, "has", 2}, {f_has, "has", 2},
{(cfunction_ptr)f_equal, "_equal", 3}, {f_equal, "_equal", 3},
{(cfunction_ptr)f_notequal, "_notequal", 3}, {f_notequal, "_notequal", 3},
{(cfunction_ptr)f_less, "_less", 3}, {f_less, "_less", 3},
{(cfunction_ptr)f_greater, "_greater", 3}, {f_greater, "_greater", 3},
{(cfunction_ptr)f_lesseq, "_lesseq", 3}, {f_lesseq, "_lesseq", 3},
{(cfunction_ptr)f_greatereq, "_greatereq", 3}, {f_greatereq, "_greatereq", 3},
{(cfunction_ptr)f_contains, "contains", 2}, {f_contains, "contains", 2},
{(cfunction_ptr)f_length, "length", 1}, {f_length, "length", 1},
{(cfunction_ptr)f_utf8bytelength, "utf8bytelength", 1}, {f_utf8bytelength, "utf8bytelength", 1},
{(cfunction_ptr)f_type, "type", 1}, {f_type, "type", 1},
{(cfunction_ptr)f_isinfinite, "isinfinite", 1}, {f_isinfinite, "isinfinite", 1},
{(cfunction_ptr)f_isnan, "isnan", 1}, {f_isnan, "isnan", 1},
{(cfunction_ptr)f_isnormal, "isnormal", 1}, {f_isnormal, "isnormal", 1},
{(cfunction_ptr)f_infinite, "infinite", 1}, {f_infinite, "infinite", 1},
{(cfunction_ptr)f_nan, "nan", 1}, {f_nan, "nan", 1},
{(cfunction_ptr)f_sort, "sort", 1}, {f_sort, "sort", 1},
{(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2}, {f_sort_by_impl, "_sort_by_impl", 2},
{(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2}, {f_group_by_impl, "_group_by_impl", 2},
{(cfunction_ptr)f_min, "min", 1}, {f_min, "min", 1},
{(cfunction_ptr)f_max, "max", 1}, {f_max, "max", 1},
{(cfunction_ptr)f_min_by_impl, "_min_by_impl", 2}, {f_min_by_impl, "_min_by_impl", 2},
{(cfunction_ptr)f_max_by_impl, "_max_by_impl", 2}, {f_max_by_impl, "_max_by_impl", 2},
{(cfunction_ptr)f_error, "error", 1}, {f_error, "error", 1},
{(cfunction_ptr)f_format, "format", 2}, {f_format, "format", 2},
{(cfunction_ptr)f_env, "env", 1}, {f_env, "env", 1},
{(cfunction_ptr)f_halt, "halt", 1}, {f_halt, "halt", 1},
{(cfunction_ptr)f_halt_error, "halt_error", 2}, {f_halt_error, "halt_error", 2},
{(cfunction_ptr)f_get_search_list, "get_search_list", 1}, {f_get_search_list, "get_search_list", 1},
{(cfunction_ptr)f_get_prog_origin, "get_prog_origin", 1}, {f_get_prog_origin, "get_prog_origin", 1},
{(cfunction_ptr)f_get_jq_origin, "get_jq_origin", 1}, {f_get_jq_origin, "get_jq_origin", 1},
{(cfunction_ptr)f_match, "_match_impl", 4}, {f_match, "_match_impl", 4},
{(cfunction_ptr)f_modulemeta, "modulemeta", 1}, {f_modulemeta, "modulemeta", 1},
{(cfunction_ptr)f_input, "input", 1}, {f_input, "input", 1},
{(cfunction_ptr)f_debug, "debug", 1}, {f_debug, "debug", 1},
{(cfunction_ptr)f_stderr, "stderr", 1}, {f_stderr, "stderr", 1},
{(cfunction_ptr)f_strptime, "strptime", 2}, {f_strptime, "strptime", 2},
{(cfunction_ptr)f_strftime, "strftime", 2}, {f_strftime, "strftime", 2},
{(cfunction_ptr)f_strflocaltime, "strflocaltime", 2}, {f_strflocaltime, "strflocaltime", 2},
{(cfunction_ptr)f_mktime, "mktime", 1}, {f_mktime, "mktime", 1},
{(cfunction_ptr)f_gmtime, "gmtime", 1}, {f_gmtime, "gmtime", 1},
{(cfunction_ptr)f_localtime, "localtime", 1}, {f_localtime, "localtime", 1},
{(cfunction_ptr)f_now, "now", 1}, {f_now, "now", 1},
{(cfunction_ptr)f_current_filename, "input_filename", 1}, {f_current_filename, "input_filename", 1},
{(cfunction_ptr)f_current_line, "input_line_number", 1}, {f_current_line, "input_line_number", 1},
}; };
#undef LIBM_DDDD_NO #undef LIBM_DDDD_NO
#undef LIBM_DDD_NO #undef LIBM_DDD_NO
+1 -2
View File
@@ -45,9 +45,8 @@ const struct opcode_description* opcode_describe(opcode op);
#define MAX_CFUNCTION_ARGS 10 #define MAX_CFUNCTION_ARGS 10
typedef void (*cfunction_ptr)();
struct cfunction { struct cfunction {
cfunction_ptr fptr; jv (*fptr)();
const char* name; const char* name;
int nargs; int nargs;
}; };
+5 -10
View File
@@ -914,17 +914,12 @@ jv jq_next(jq_state *jq) {
in[i] = stack_pop(jq); in[i] = stack_pop(jq);
} }
struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++]; struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++];
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) { switch (function->nargs) {
case 1: top = ((func_1)function->fptr)(jq, in[0]); break; case 1: top = function->fptr(jq, in[0]); break;
case 2: top = ((func_2)function->fptr)(jq, in[0], in[1]); break; case 2: top = function->fptr(jq, in[0], in[1]); break;
case 3: top = ((func_3)function->fptr)(jq, in[0], in[1], in[2]); break; case 3: top = 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 4: top = 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; case 5: top = 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 // FIXME: a) up to 7 arguments (input + 6), b) should assert
// because the compiler should not generate this error. // because the compiler should not generate this error.
default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); default: return jv_invalid_with_msg(jv_string("Function takes too many arguments"));