Skip to content

Commit

Permalink
Merge pull request #241 from alltilla/filterx-generator-function
Browse files Browse the repository at this point in the history
filterx: generator functions support
  • Loading branch information
OverOrion authored Aug 13, 2024
2 parents d356f61 + 72cc250 commit 73a8cd6
Show file tree
Hide file tree
Showing 29 changed files with 377 additions and 128 deletions.
5 changes: 4 additions & 1 deletion lib/cfg-grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,10 @@ main_location_print (FILE *yyo, YYLTYPE const * const yylocp)
%token LL_CONTEXT_FILTERX_SIMPLE_FUNC 24
%token LL_CONTEXT_FILTERX_ENUM 25
%token LL_CONTEXT_FILTERX_FUNC 26
%token LL_CONTEXT_FILTERX_GEN_FUNC 27

/* this is a placeholder for unit tests, must be the latest & largest */
%token LL_CONTEXT_MAX 27
%token LL_CONTEXT_MAX 28


%left ';'
Expand Down Expand Up @@ -409,6 +410,8 @@ main_location_print (FILE *yyo, YYLTYPE const * const yylocp)
%token <cptr> LL_PLUGIN 10436
%token <cptr> LL_TEMPLATE_REF 10437
%token <cptr> LL_MESSAGE_REF 10438
%token <cptr> LL_FILTERX_FUNC 10439
%token <cptr> LL_FILTERX_GEN_FUNC 10440

%destructor { free($$); } <cptr>

Expand Down
22 changes: 22 additions & 0 deletions lib/cfg-lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "pathutils.h"
#include "plugin.h"
#include "plugin-types.h"
#include "filterx/filterx-globals.h"

#include <string.h>
#include <glob.h>
Expand Down Expand Up @@ -1219,6 +1220,26 @@ cfg_lexer_lex(CfgLexer *self, CFG_STYPE *yylval, CFG_LTYPE *yylloc)
}
}
}

if (cfg_lexer_get_context_type(self) == LL_CONTEXT_FILTERX)
{
if (tok == LL_IDENTIFIER)
{
PluginContext *plugin_context = &self->cfg->plugin_context;

if ((self->cfg && plugin_is_plugin_available(plugin_context, LL_CONTEXT_FILTERX_FUNC, yylval->cptr)) ||
(self->cfg && plugin_is_plugin_available(plugin_context, LL_CONTEXT_FILTERX_SIMPLE_FUNC, yylval->cptr)) ||
filterx_builtin_function_exists(yylval->cptr))
{
tok = LL_FILTERX_FUNC;
}
else if ((self->cfg && plugin_is_plugin_available(plugin_context, LL_CONTEXT_FILTERX_GEN_FUNC, yylval->cptr)) ||
filterx_builtin_generator_function_exists(yylval->cptr))
{
tok = LL_FILTERX_GEN_FUNC;
}
}
}
}

preprocess_result = cfg_lexer_preprocess(self, tok, yylval, yylloc);
Expand Down Expand Up @@ -1342,6 +1363,7 @@ static const gchar *lexer_contexts[] =
[LL_CONTEXT_FILTERX_SIMPLE_FUNC] = "filterx-simple-func",
[LL_CONTEXT_FILTERX_ENUM] = "filterx-enum",
[LL_CONTEXT_FILTERX_FUNC] = "filterx-func",
[LL_CONTEXT_FILTERX_GEN_FUNC] = "filterx-gen-func",
};

gint
Expand Down
64 changes: 60 additions & 4 deletions lib/filterx/expr-function.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,28 @@ filterx_function_init_instance(FilterXFunction *s, const gchar *function_name)
s->super.free_fn = _function_free;
}

void
filterx_generator_function_free_method(FilterXGeneratorFunction *s)
{
g_free(s->function_name);
filterx_generator_free_method(&s->super.super);
}

static void
_generator_function_free(FilterXExpr *s)
{
FilterXGeneratorFunction *self = (FilterXGeneratorFunction *) s;
filterx_generator_function_free_method(self);
}

void
filterx_generator_function_init_instance(FilterXGeneratorFunction *s, const gchar *function_name)
{
filterx_generator_init_instance(&s->super.super);
s->function_name = g_strdup_printf("%s()", function_name);
s->super.super.free_fn = _generator_function_free;
}

struct _FilterXFunctionArgs
{
GPtrArray *positional_args;
Expand Down Expand Up @@ -549,10 +571,7 @@ _lookup_function(GlobalConfig *cfg, const gchar *function_name, FilterXFunctionA
if (!ctor)
return NULL;

FilterXFunction *func_expr = ctor(function_name, args, error);
if (!func_expr)
return NULL;
return &func_expr->super;
return ctor(function_name, args, error);
}

/* NOTE: takes the reference of "args_list" */
Expand All @@ -575,3 +594,40 @@ filterx_function_lookup(GlobalConfig *cfg, const gchar *function_name, GList *ar
g_set_error(error, FILTERX_FUNCTION_ERROR, FILTERX_FUNCTION_ERROR_FUNCTION_NOT_FOUND, "function not found");
return NULL;
}

static FilterXExpr *
_lookup_generator_function(GlobalConfig *cfg, const gchar *function_name, FilterXFunctionArgs *args, GError **error)
{
// Checking filterx builtin generator functions first
FilterXFunctionCtor ctor = filterx_builtin_generator_function_ctor_lookup(function_name);

if (!ctor)
{
// fallback to plugin lookup
Plugin *p = cfg_find_plugin(cfg, LL_CONTEXT_FILTERX_GEN_FUNC, function_name);
if (!p)
return NULL;
ctor = plugin_construct(p);
}

if (!ctor)
return NULL;
return ctor(function_name, args, error);
}

/* NOTE: takes the references of objects passed in "arguments" */
FilterXExpr *
filterx_generator_function_lookup(GlobalConfig *cfg, const gchar *function_name, GList *args_list, GError **error)
{
FilterXFunctionArgs *args = filterx_function_args_new(args_list, error);
if (!args)
return NULL;

FilterXExpr *expr = _lookup_generator_function(cfg, function_name, args, error);
if (expr)
return expr;

if (!(*error))
g_set_error(error, FILTERX_FUNCTION_ERROR, FILTERX_FUNCTION_ERROR_FUNCTION_NOT_FOUND, "function not found");
return NULL;
}
34 changes: 33 additions & 1 deletion lib/filterx/expr-function.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "filterx/filterx-expr.h"
#include "filterx/filterx-object.h"
#include "filterx/expr-generator.h"
#include "generic-number.h"
#include "plugin.h"

Expand All @@ -41,6 +42,12 @@ typedef struct _FilterXFunction
gchar *function_name;
} FilterXFunction;

typedef struct _FilterXGeneratorFunction
{
FilterXExprGenerator super;
gchar *function_name;
} FilterXGeneratorFunction;

typedef struct _FilterXFunctionArgs FilterXFunctionArgs;
typedef struct _FilterXFunctionArg
{
Expand All @@ -49,7 +56,7 @@ typedef struct _FilterXFunctionArg
gboolean retrieved;
} FilterXFunctionArg;

typedef FilterXFunction *(*FilterXFunctionCtor)(const gchar *, FilterXFunctionArgs *, GError **);
typedef FilterXExpr *(*FilterXFunctionCtor)(const gchar *, FilterXFunctionArgs *, GError **);

#define FILTERX_FUNCTION_ERROR filterx_function_error_quark()
GQuark filterx_function_error_quark(void);
Expand All @@ -63,6 +70,8 @@ enum FilterXFunctionError

void filterx_function_init_instance(FilterXFunction *s, const gchar *function_name);
void filterx_function_free_method(FilterXFunction *s);
void filterx_generator_function_init_instance(FilterXGeneratorFunction *s, const gchar *function_name);
void filterx_generator_function_free_method(FilterXGeneratorFunction *s);

FilterXFunctionArg *filterx_function_arg_new(const gchar *name, FilterXExpr *value);
FilterXFunctionArgs *filterx_function_args_new(GList *args, GError **error);
Expand Down Expand Up @@ -90,6 +99,8 @@ gboolean filterx_function_args_check(FilterXFunctionArgs *self, GError **error);
void filterx_function_args_free(FilterXFunctionArgs *self);

FilterXExpr *filterx_function_lookup(GlobalConfig *cfg, const gchar *function_name, GList *args, GError **error);
FilterXExpr *filterx_generator_function_lookup(GlobalConfig *cfg, const gchar *function_name, GList *args,
GError **error);


#define FILTERX_SIMPLE_FUNCTION_PROTOTYPE(func_name) \
Expand Down Expand Up @@ -135,4 +146,25 @@ FilterXExpr *filterx_function_lookup(GlobalConfig *cfg, const gchar *function_na
.construct = filterx_function_ ## func_name ## _construct, \
}

#define FILTERX_GENERATOR_FUNCTION_PROTOTYPE(func_name) \
gpointer \
filterx_generator_function_ ## func_name ## _construct(Plugin *self)

#define FILTERX_GENERATOR_FUNCTION_DECLARE(func_name) \
FILTERX_GENERATOR_FUNCTION_PROTOTYPE(func_name);

#define FILTERX_GENERATOR_FUNCTION(func_name, ctor) \
FILTERX_GENERATOR_FUNCTION_PROTOTYPE(func_name) \
{ \
FilterXFunctionCtor f = ctor; \
return (gpointer) f; \
}

#define FILTERX_GENERATOR_FUNCTION_PLUGIN(func_name) \
{ \
.type = LL_CONTEXT_FILTERX_GEN_FUNC, \
.name = # func_name, \
.construct = filterx_generator_function_ ## func_name ## _construct, \
}

#endif
74 changes: 56 additions & 18 deletions lib/filterx/expr-regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,19 @@
#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"

#define FILTERX_FUNC_REGEXP_SUBST_USAGE "regexp_subst(string, pattern, replacement, " \
#define FILTERX_FUNC_REGEXP_SUBST_USAGE "Usage: regexp_subst(string, pattern, replacement, " \
FILTERX_FUNC_REGEXP_SUBST_FLAG_JIT_NAME"=(boolean) " \
FILTERX_FUNC_REGEXP_SUBST_FLAG_GLOBAL_NAME"=(boolean) " \
FILTERX_FUNC_REGEXP_SUBST_FLAG_UTF8_NAME"=(boolean) " \
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 Expand Up @@ -661,7 +699,7 @@ _opts_init(FilterXFuncRegexpSubstOpts *opts)
opts->jit = TRUE;
}

FilterXFunction *
FilterXExpr *
filterx_function_regexp_subst_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error)
{
FilterXFuncRegexpSubst *self = g_new0(FilterXFuncRegexpSubst, 1);
Expand All @@ -676,7 +714,7 @@ filterx_function_regexp_subst_new(const gchar *function_name, FilterXFunctionArg
goto error;

filterx_function_args_free(args);
return &self->super;
return &self->super.super;

error:
filterx_function_args_free(args);
Expand All @@ -685,7 +723,7 @@ filterx_function_regexp_subst_new(const gchar *function_name, FilterXFunctionArg
}

gboolean
filterx_regexp_subst_is_jit_enabled(FilterXFunction *s)
filterx_regexp_subst_is_jit_enabled(FilterXExpr *s)
{
g_assert(s);
FilterXFuncRegexpSubst *self = (FilterXFuncRegexpSubst *)s;
Expand Down
8 changes: 4 additions & 4 deletions lib/filterx/expr-regexp.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ 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);
FilterXFunction *filterx_function_regexp_subst_new(const gchar *function_name, FilterXFunctionArgs *args,
GError **error);
gboolean filterx_regexp_subst_is_jit_enabled(FilterXFunction *s);
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);

#endif
4 changes: 2 additions & 2 deletions lib/filterx/expr-unset.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ _free(FilterXExpr *s)
filterx_function_free_method(&self->super);
}

FilterXFunction *
FilterXExpr *
filterx_function_unset_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error)
{
FilterXExprUnset *self = g_new0(FilterXExprUnset, 1);
Expand All @@ -72,7 +72,7 @@ filterx_function_unset_new(const gchar *function_name, FilterXFunctionArgs *args
goto error;

filterx_function_args_free(args);
return &self->super;
return &self->super.super;

error:
filterx_function_args_free(args);
Expand Down
2 changes: 1 addition & 1 deletion lib/filterx/expr-unset.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@

#include "filterx/expr-function.h"

FilterXFunction *filterx_function_unset_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error);
FilterXExpr *filterx_function_unset_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error);

#endif
Loading

0 comments on commit 73a8cd6

Please sign in to comment.