From e13a754bf4b86871f398763a376930c1ec32edd3 Mon Sep 17 00:00:00 2001 From: Attila Szakacs Date: Wed, 7 Aug 2024 15:41:33 +0200 Subject: [PATCH] filterx/expr-regexp: transform regexp_search() to generator fn Signed-off-by: Attila Szakacs --- lib/filterx/expr-regexp.c | 66 ++++++++++++++++++++++------ lib/filterx/expr-regexp.h | 3 +- lib/filterx/filterx-globals.c | 2 + lib/filterx/filterx-grammar.ym | 7 --- lib/filterx/filterx-parser.c | 3 -- lib/filterx/tests/test_expr_regexp.c | 26 +++++++++-- 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/lib/filterx/expr-regexp.c b/lib/filterx/expr-regexp.c index 8e2381cfed..e41be59a7a 100644 --- a/lib/filterx/expr-regexp.c +++ b/lib/filterx/expr-regexp.c @@ -27,6 +27,7 @@ #include "filterx/object-string.h" #include "filterx/object-list-interface.h" #include "filterx/object-dict-interface.h" +#include "filterx/expr-function.h" #include "compat/pcre.h" #include "scratch-buffers.h" @@ -37,6 +38,8 @@ FILTERX_FUNC_REGEXP_SUBST_FLAG_IGNORECASE_NAME"=(boolean) " \ FILTERX_FUNC_REGEXP_SUBST_FLAG_NEWLINE_NAME"=(boolean))" \ +#define FILTERX_FUNC_REGEXP_SEARCH_USAGE "Usage: regexp_search(string, pattern)" + typedef struct FilterXReMatchState_ { pcre2_match_data *match_data; @@ -350,7 +353,7 @@ filterx_expr_regexp_nomatch_new(FilterXExpr *lhs, const gchar *pattern) typedef struct FilterXExprRegexpSearchGenerator_ { - FilterXExprGenerator super; + FilterXGeneratorFunction super; FilterXExpr *lhs; pcre2_code_8 *pattern; } FilterXExprRegexpSearchGenerator; @@ -412,31 +415,66 @@ _regexp_search_generator_free(FilterXExpr *s) filterx_expr_unref(self->lhs); if (self->pattern) pcre2_code_free(self->pattern); - filterx_generator_free_method(s); + filterx_generator_function_free_method(&self->super); } -/* Takes reference of lhs */ -FilterXExpr * -filterx_expr_regexp_search_generator_new(FilterXExpr *lhs, const gchar *pattern) +static gboolean +_extract_search_args(FilterXExprRegexpSearchGenerator *self, FilterXFunctionArgs *args, GError **error) { - FilterXExprRegexpSearchGenerator *self = g_new0(FilterXExprRegexpSearchGenerator, 1); + if (filterx_function_args_len(args) != 2) + { + g_set_error(error, FILTERX_FUNCTION_ERROR, FILTERX_FUNCTION_ERROR_CTOR_FAIL, + "invalid number of arguments. " FILTERX_FUNC_REGEXP_SEARCH_USAGE); + return FALSE; + } - filterx_generator_init_instance(&self->super.super); - self->super.generate = _regexp_search_generator_generate; - self->super.super.free_fn = _regexp_search_generator_free; - self->super.create_container = _regexp_search_generator_create_container; + self->lhs = filterx_function_args_get_expr(args, 0); + + const gchar *pattern = filterx_function_args_get_literal_string(args, 1, NULL); + if (!pattern) + { + g_set_error(error, FILTERX_FUNCTION_ERROR, FILTERX_FUNCTION_ERROR_CTOR_FAIL, + "pattern must be string literal. " FILTERX_FUNC_REGEXP_SEARCH_USAGE); + return FALSE; + } - self->lhs = lhs; self->pattern = _compile_pattern_defaults(pattern); if (!self->pattern) { - filterx_expr_unref(&self->super.super); - return NULL; + g_set_error(error, FILTERX_FUNCTION_ERROR, FILTERX_FUNCTION_ERROR_CTOR_FAIL, + "failed to compile pattern. " FILTERX_FUNC_REGEXP_SEARCH_USAGE); + return FALSE; } - return &self->super.super; + return TRUE; + +} + +/* Takes reference of lhs */ +FilterXExpr * +filterx_generator_function_regexp_search_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error) +{ + FilterXExprRegexpSearchGenerator *self = g_new0(FilterXExprRegexpSearchGenerator, 1); + + filterx_generator_function_init_instance(&self->super, function_name); + self->super.super.generate = _regexp_search_generator_generate; + self->super.super.super.free_fn = _regexp_search_generator_free; + self->super.super.create_container = _regexp_search_generator_create_container; + + if (!_extract_search_args(self, args, error) || + !filterx_function_args_check(args, error)) + goto error; + + filterx_function_args_free(args); + return &self->super.super.super; + +error: + filterx_function_args_free(args); + filterx_expr_unref(&self->super.super.super); + return NULL; } + typedef struct FilterXFuncRegexpSubst_ { FilterXFunction super; diff --git a/lib/filterx/expr-regexp.h b/lib/filterx/expr-regexp.h index 81530fe267..ca63d2556e 100644 --- a/lib/filterx/expr-regexp.h +++ b/lib/filterx/expr-regexp.h @@ -45,7 +45,8 @@ typedef struct FilterXFuncRegexpSubstOpts_ FilterXExpr *filterx_expr_regexp_match_new(FilterXExpr *lhs, const gchar *pattern); FilterXExpr *filterx_expr_regexp_nomatch_new(FilterXExpr *lhs, const gchar *pattern); -FilterXExpr *filterx_expr_regexp_search_generator_new(FilterXExpr *lhs, const gchar *pattern); +FilterXExpr *filterx_generator_function_regexp_search_new(const gchar *function_name, FilterXFunctionArgs *args, + GError **error); FilterXExpr *filterx_function_regexp_subst_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error); gboolean filterx_regexp_subst_is_jit_enabled(FilterXExpr *s); diff --git a/lib/filterx/filterx-globals.c b/lib/filterx/filterx-globals.c index 284fc74dbb..15840114a7 100644 --- a/lib/filterx/filterx-globals.c +++ b/lib/filterx/filterx-globals.c @@ -159,6 +159,8 @@ static void _generator_ctors_init(void) { filterx_builtin_function_ctors_init_private(&filterx_builtin_generator_function_ctors); + g_assert(filterx_builtin_generator_function_ctor_register("regexp_search", + filterx_generator_function_regexp_search_new)); } static void diff --git a/lib/filterx/filterx-grammar.ym b/lib/filterx/filterx-grammar.ym index da75e96135..0703ec3d8b 100644 --- a/lib/filterx/filterx-grammar.ym +++ b/lib/filterx/filterx-grammar.ym @@ -105,7 +105,6 @@ construct_template_expr(LogTemplate *template) %token KW_ENUM %token KW_ISSET %token KW_DECLARE -%token KW_REGEXP_SEARCH %type block %type stmts @@ -140,7 +139,6 @@ construct_template_expr(LogTemplate *template) %type inner_list_generator %type list_element %type list_elements -%type regexp_search %type regexp_match %type boolean %type conditional @@ -372,7 +370,6 @@ expr_generator_unchecked : dict_generator | list_generator | generator_function_call - | regexp_search | '(' expr_generator ')' { $$ = $2; } | expr '+' expr_generator { $$ = filterx_operator_plus_generator_new($1, $3); } | expr_generator '+' expr { $$ = filterx_operator_plus_generator_new($1, $3); } @@ -521,10 +518,6 @@ list_element | inner_list_generator { $$ = filterx_literal_generator_elem_new(NULL, $1, FALSE); } ; -regexp_search - : KW_REGEXP_SEARCH '(' expr ',' string ')' { $$ = filterx_expr_regexp_search_generator_new($3, $5); free($5); } - ; - regexp_match : expr KW_REGEXP_MATCH string { $$ = filterx_expr_regexp_match_new($1, $3); free($3); } | expr KW_REGEXP_NOMATCH string { $$ = filterx_expr_regexp_nomatch_new($1, $3); free($3); } diff --git a/lib/filterx/filterx-parser.c b/lib/filterx/filterx-parser.c index 979cdfff2e..6c7b77c52a 100644 --- a/lib/filterx/filterx-parser.c +++ b/lib/filterx/filterx-parser.c @@ -51,9 +51,6 @@ static CfgLexerKeyword filterx_keywords[] = { "isset", KW_ISSET }, { "declare", KW_DECLARE }, - /* TODO: This should be done via generator function. */ - { "regexp_search", KW_REGEXP_SEARCH }, - { CFG_KEYWORD_STOP }, }; diff --git a/lib/filterx/tests/test_expr_regexp.c b/lib/filterx/tests/test_expr_regexp.c index 5627221060..0cefdc6bc8 100644 --- a/lib/filterx/tests/test_expr_regexp.c +++ b/lib/filterx/tests/test_expr_regexp.c @@ -80,7 +80,11 @@ Test(filterx_expr_regexp, regexp_match) static FilterXObject * _search(const gchar *lhs, const gchar *pattern) { - FilterXExpr *expr = filterx_expr_regexp_search_generator_new(filterx_literal_new(filterx_string_new(lhs, -1)), pattern); + GList *args = NULL; + args = g_list_append(args, filterx_function_arg_new(NULL, filterx_non_literal_new(filterx_string_new(lhs, -1)))); + args = g_list_append(args, filterx_function_arg_new(NULL, filterx_literal_new(filterx_string_new(pattern, -1)))); + + FilterXExpr *expr = filterx_generator_function_regexp_search_new("test", filterx_function_args_new(args, NULL), NULL); FilterXExpr *parent_fillable_expr_new = filterx_literal_new(filterx_test_dict_new()); FilterXExpr *cc_expr = filterx_generator_create_container_new(expr, parent_fillable_expr_new); FilterXExpr *fillable_expr = filterx_literal_new(filterx_expr_eval(cc_expr)); @@ -104,7 +108,12 @@ _search(const gchar *lhs, const gchar *pattern) static void _search_with_fillable(const gchar *lhs, const gchar *pattern, FilterXObject *fillable) { - FilterXExpr *expr = filterx_expr_regexp_search_generator_new(filterx_literal_new(filterx_string_new(lhs, -1)), pattern); + GList *args = NULL; + args = g_list_append(args, filterx_function_arg_new(NULL, filterx_non_literal_new(filterx_string_new(lhs, -1)))); + args = g_list_append(args, filterx_function_arg_new(NULL, filterx_literal_new(filterx_string_new(pattern, -1)))); + + FilterXExpr *expr = filterx_generator_function_regexp_search_new("test", + filterx_function_args_new(args, NULL), NULL); filterx_generator_set_fillable(expr, filterx_literal_new(filterx_object_ref(fillable))); FilterXObject *result_obj = filterx_expr_eval(expr); @@ -118,7 +127,18 @@ _search_with_fillable(const gchar *lhs, const gchar *pattern, FilterXObject *fil static void _assert_search_init_error(const gchar *lhs, const gchar *pattern) { - cr_assert_not(filterx_expr_regexp_search_generator_new(filterx_literal_new(filterx_string_new(lhs, -1)), pattern)); + GList *args = NULL; + args = g_list_append(args, filterx_function_arg_new(NULL, filterx_non_literal_new(filterx_string_new(lhs, -1)))); + args = g_list_append(args, filterx_function_arg_new(NULL, filterx_literal_new(filterx_string_new(pattern, -1)))); + + GError *arg_err = NULL; + GError *func_err = NULL; + cr_assert_not(filterx_generator_function_regexp_search_new("test", + filterx_function_args_new(args, &arg_err), &func_err)); + + cr_assert(arg_err || func_err); + g_clear_error(&arg_err); + g_clear_error(&func_err); } static void