Skip to content

Commit

Permalink
filterx/expr-regexp: transform regexp_search() to generator fn
Browse files Browse the repository at this point in the history
Signed-off-by: Attila Szakacs <[email protected]>
  • Loading branch information
alltilla committed Aug 13, 2024
1 parent 0cad7b4 commit e13a754
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 28 deletions.
66 changes: 52 additions & 14 deletions lib/filterx/expr-regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion lib/filterx/expr-regexp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions lib/filterx/filterx-globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 0 additions & 7 deletions lib/filterx/filterx-grammar.ym
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ construct_template_expr(LogTemplate *template)
%token KW_ENUM
%token KW_ISSET
%token KW_DECLARE
%token KW_REGEXP_SEARCH

%type <ptr> block
%type <ptr> stmts
Expand Down Expand Up @@ -140,7 +139,6 @@ construct_template_expr(LogTemplate *template)
%type <ptr> inner_list_generator
%type <ptr> list_element
%type <ptr> list_elements
%type <ptr> regexp_search
%type <ptr> regexp_match
%type <num> boolean
%type <ptr> conditional
Expand Down Expand Up @@ -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); }
Expand Down Expand Up @@ -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); }
Expand Down
3 changes: 0 additions & 3 deletions lib/filterx/filterx-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
};

Expand Down
26 changes: 23 additions & 3 deletions lib/filterx/tests/test_expr_regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);
Expand All @@ -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
Expand Down

0 comments on commit e13a754

Please sign in to comment.