Skip to content

Commit

Permalink
Merge pull request #238 from bshifter/filterx-regex-nomatch
Browse files Browse the repository at this point in the history
filterx: add !~ operator counterpart for =~
  • Loading branch information
MrAnno authored Aug 7, 2024
2 parents 8581cd8 + 9d12ada commit 5b88f1c
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 4 deletions.
5 changes: 2 additions & 3 deletions lib/cfg-grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,13 @@ main_location_print (FILE *yyo, YYLTYPE const * const yylocp)

/* operators in the filter language, the order of this determines precedence */
%right KW_ASSIGN 9000
%right KW_PLUS_ASSIGN 9001
%right '?' ':'
%right KW_NULL_COALESCING
%left KW_OR 9010
%left KW_AND 9020
%left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035
%left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035, KW_REGEXP_MATCH 9036, KW_REGEXP_NOMATCH 9037
%left KW_STR_LT 9040, KW_STR_LE 9041, KW_STR_GE, 9042 KW_STR_GT, 9043, KW_TA_LT 9044, KW_TA_LE 9045, KW_TA_GE 9046, KW_TA_GT 9047
%right KW_PLUS_ASSIGN 9050
%left KW_REGEXP_MATCH 9060

%left '+' '-'
%left '*'
Expand Down
1 change: 1 addition & 0 deletions lib/cfg-lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ filterx_word [^ \#'"/\(\)\{\}\[\]\\;\r\n\t,|\.@:]
<INITIAL,filterx>!== { return KW_TAV_NE; }
<filterx>\+= { return KW_PLUS_ASSIGN; }
<filterx>=~ { return KW_REGEXP_MATCH; }
<filterx>!~ { return KW_REGEXP_NOMATCH; }
<filterx>\?\? { return KW_NULL_COALESCING; }
<INITIAL,filterx>(-|\+)?{digit}+\.{digit}+ { yylval->fnum = strtod(yytext, NULL); return LL_FLOAT; }
Expand Down
10 changes: 9 additions & 1 deletion lib/filterx/expr-regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ typedef struct FilterXExprRegexpMatch_
FilterXExpr super;
FilterXExpr *lhs;
pcre2_code_8 *pattern;
gboolean invert;
} FilterXExprRegexpMatch;

static FilterXObject *
Expand All @@ -300,7 +301,7 @@ _regexp_match_eval(FilterXExpr *s)
goto exit;
}

result = filterx_boolean_new(matched);
result = filterx_boolean_new(matched != self->invert);

exit:
_state_cleanup(&state);
Expand Down Expand Up @@ -339,6 +340,13 @@ filterx_expr_regexp_match_new(FilterXExpr *lhs, const gchar *pattern)
return &self->super;
}

FilterXExpr *
filterx_expr_regexp_nomatch_new(FilterXExpr *lhs, const gchar *pattern)
{
FilterXExprRegexpMatch *self = (FilterXExprRegexpMatch *)filterx_expr_regexp_match_new(lhs, pattern);
self->invert = TRUE;
return &self->super;
}

typedef struct FilterXExprRegexpSearchGenerator_
{
Expand Down
1 change: 1 addition & 0 deletions lib/filterx/expr-regexp.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef struct FilterXFuncRegexpSubstOpts_
} 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);
Expand Down
1 change: 1 addition & 0 deletions lib/filterx/filterx-grammar.ym
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ regexp_search

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); }
;

conditional
Expand Down
26 changes: 26 additions & 0 deletions tests/light/functional_tests/filterx/test_filterx.py
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,32 @@ def test_regexp_match(config, syslog_ng):
assert file_true.read_log() == "success\n"


def test_regexp_nomatch(config, syslog_ng):
(file_true, file_false) = create_config(
config, r"""
$MSG = json();
$MSG.match = ${values.str} !~ /string/;
$MSG.match_any = ${values.str} !~ /.*/;
$MSG.nomatch = ${values.str} !~ /wrong/;
$MSG.match_inverse = not (${values.str} !~ /.*/);
$MSG.nomatch_inverse = not (${values.str} !~ /foobar/);
""",
)
syslog_ng.start(config)

exp = (
r"""{"match":false,"""
r""""match_any":false,"""
r""""nomatch":true,"""
r""""match_inverse":true,"""
r""""nomatch_inverse":false}""" + "\n"
)

assert file_true.get_stats()["processed"] == 1
assert "processed" not in file_false.get_stats()
assert file_true.read_log() == exp


def test_regexp_match_error_in_pattern(config, syslog_ng):
_ = create_config(
config, r"""
Expand Down

0 comments on commit 5b88f1c

Please sign in to comment.