From e2a3acefe9e36d01d787c83125b4e31890b3ee17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Tue, 24 Oct 2023 18:49:49 +0100 Subject: [PATCH] dfilter: Use a constant to declare function return type Simplify the interface to declare the function. This also makes it easier to infer the function return type from a compiled filter. Print the function return type when dumping the compiled filter or <***> if the type is unknown from the function name. --- epan/dfilter/dfunctions.c | 44 ++++++++------------------------------- epan/dfilter/dfunctions.h | 6 ++---- epan/dfilter/dfvm.c | 15 +++++++++---- epan/dfilter/semcheck.c | 11 +++++++++- 4 files changed, 32 insertions(+), 44 deletions(-) diff --git a/epan/dfilter/dfunctions.c b/epan/dfilter/dfunctions.c index db4526363b..2da4b9100d 100644 --- a/epan/dfilter/dfunctions.c +++ b/epan/dfilter/dfunctions.c @@ -430,45 +430,19 @@ ul_semcheck_absolute_value(dfwork_t *dfw, const char *func_name, ftenum_t logica return ftype; } -static ftenum_t -return_string(GSList *param_list _U_) -{ - return FT_STRING; -} - -static ftenum_t -return_unsigned(GSList *param_list _U_) -{ - return FT_UINT32; -} - -static ftenum_t -return_compare(GSList *param_list) -{ - GSList *l; - ftenum_t ftype; - - for (l = param_list; l != NULL; l = l->next) { - ftype = get_logical_ftype(l->data); - if (ftype != FT_NONE) - return ftype; - } - return FT_NONE; -} - /* The table of all display-filter functions */ static df_func_def_t df_functions[] = { - { "lower", df_func_lower, 1, 1, return_string, ul_semcheck_is_field_string }, - { "upper", df_func_upper, 1, 1, return_string, ul_semcheck_is_field_string }, + { "lower", df_func_lower, 1, 1, FT_STRING, ul_semcheck_is_field_string }, + { "upper", df_func_upper, 1, 1, FT_STRING, ul_semcheck_is_field_string }, /* Length function is implemented as a DFVM instruction. */ - { "len", NULL, 1, 1, return_unsigned, ul_semcheck_can_length }, - { "count", df_func_count, 1, 1, return_unsigned, ul_semcheck_is_field }, - { "string", df_func_string, 1, 1, return_string, ul_semcheck_string_param }, - { "max", df_func_max, 1, 0, return_compare, ul_semcheck_compare }, - { "min", df_func_min, 1, 0, return_compare, ul_semcheck_compare }, - { "abs", df_func_abs, 1, 1, return_compare, ul_semcheck_absolute_value }, - { NULL, NULL, 0, 0, NULL, NULL } + { "len", NULL, 1, 1, FT_UINT32, ul_semcheck_can_length }, + { "count", df_func_count, 1, 1, FT_UINT32, ul_semcheck_is_field }, + { "string", df_func_string, 1, 1, FT_STRING, ul_semcheck_string_param }, + { "max", df_func_max, 1, 0, FT_NONE, ul_semcheck_compare }, + { "min", df_func_min, 1, 0, FT_NONE, ul_semcheck_compare }, + { "abs", df_func_abs, 1, 1, FT_NONE, ul_semcheck_absolute_value }, + { NULL, NULL, 0, 0, FT_NONE, NULL } }; /* Lookup a display filter function record by name */ diff --git a/epan/dfilter/dfunctions.h b/epan/dfilter/dfunctions.h index dde87d091a..2586e1b0d5 100644 --- a/epan/dfilter/dfunctions.h +++ b/epan/dfilter/dfunctions.h @@ -20,9 +20,6 @@ /* The run-time logic of the dfilter function */ typedef bool (*DFFuncType)(GSList *stack, uint32_t arg_count, df_cell_t *retval); -/* The return type for the dfilter function */ -typedef ftenum_t (*DFReturnType)(GSList *param_list); - /* The semantic check for the dfilter function */ typedef ftenum_t (*DFSemCheckType)(dfwork_t *dfw, const char *func_name, ftenum_t lhs_ftype, GSList *param_list, df_loc_t func_loc); @@ -34,7 +31,8 @@ typedef struct { DFFuncType function; unsigned min_nargs; unsigned max_nargs; /* 0 for no limit */ - DFReturnType return_type; + ftenum_t return_ftype; /* Can be FT_NONE if the function returns the same type + * as its arguments. */ DFSemCheckType semcheck_param_function; } df_func_def_t; diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c index a64e57bd05..178250c2c0 100644 --- a/epan/dfilter/dfvm.c +++ b/epan/dfilter/dfvm.c @@ -281,6 +281,12 @@ value_type_tostr(dfvm_value_t *v, bool show_ftype) case FVALUE: s = fvalue_type_name(dfvm_value_get_fvalue(v)); break; + case FUNCTION_DEF: + if (v->value.funcdef->return_ftype != FT_NONE) + s = ftype_name(v->value.funcdef->return_ftype); + else + s = "***"; + break; default: return ws_strdup(""); break; @@ -305,8 +311,8 @@ dump_str_stack_pop(GSList *stack, uint32_t count) } static void -append_call_function(wmem_strbuf_t *buf, const char *func, uint32_t nargs, - GSList *stack_print) +append_call_function(wmem_strbuf_t *buf, const char *func, const char *func_type, + uint32_t nargs, GSList *stack_print) { uint32_t idx; GString *gs; @@ -324,7 +330,7 @@ append_call_function(wmem_strbuf_t *buf, const char *func, uint32_t nargs, wmem_strbuf_append(buf, gs->str); g_string_free(gs, true); } - wmem_strbuf_append(buf, ")"); + wmem_strbuf_append_printf(buf, ")%s", func_type); } static void @@ -412,7 +418,8 @@ append_op_args(wmem_strbuf_t *buf, dfvm_insn_t *insn, GSList **stack_print, break; case DFVM_CALL_FUNCTION: - append_call_function(buf, arg1_str, arg3->value.numeric, *stack_print); + append_call_function(buf, arg1_str, arg1_str_type, + arg3->value.numeric, *stack_print); indent2(buf, col_start); append_to_register(buf, arg2_str); break; diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 76f501728a..d3c9de183d 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -674,9 +674,18 @@ get_function_ftype(stnode_t *st_node) params = sttype_function_params(st_node); nparams = g_slist_length(params); + if (funcdef->return_ftype != FT_NONE) + return funcdef->return_ftype; if (nparams < 1) return FT_NONE; - return funcdef->return_type(params); + + for (GSList *l = params; l != NULL; l = l->next) { + ftenum_t ftype = get_logical_ftype(params->data); + if (ftype != FT_NONE) { + return ftype; + } + } + return FT_NONE; } ftenum_t