diff --git a/lib/filterx/CMakeLists.txt b/lib/filterx/CMakeLists.txt index 3ec0c641d8..92d112c69a 100644 --- a/lib/filterx/CMakeLists.txt +++ b/lib/filterx/CMakeLists.txt @@ -38,6 +38,7 @@ set(FILTERX_HEADERS filterx/filterx-private.h filterx/func-istype.h filterx/func-len.h + filterx/expr-plus.h PARENT_SCOPE ) @@ -81,6 +82,7 @@ set(FILTERX_SOURCES filterx/expr-regexp.c filterx/func-istype.c filterx/func-len.c + filterx/expr-plus.c filterx/filterx-private.c PARENT_SCOPE ) diff --git a/lib/filterx/Makefile.am b/lib/filterx/Makefile.am index 8b495f5051..69b2172795 100644 --- a/lib/filterx/Makefile.am +++ b/lib/filterx/Makefile.am @@ -12,6 +12,7 @@ filterxinclude_HEADERS = \ lib/filterx/expr-setattr.h \ lib/filterx/expr-get-subscript.h \ lib/filterx/expr-set-subscript.h \ + lib/filterx/expr-plus.h \ lib/filterx/expr-variable.h \ lib/filterx/expr-comparison.h \ lib/filterx/filterx-object.h \ @@ -54,6 +55,7 @@ filterx_sources = \ lib/filterx/expr-setattr.c \ lib/filterx/expr-get-subscript.c \ lib/filterx/expr-set-subscript.c \ + lib/filterx/expr-plus.c \ lib/filterx/expr-variable.c \ lib/filterx/expr-comparison.c \ lib/filterx/filterx-object.c \ diff --git a/lib/filterx/expr-plus.c b/lib/filterx/expr-plus.c new file mode 100644 index 0000000000..9f66b0688e --- /dev/null +++ b/lib/filterx/expr-plus.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Balazs Scheidler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ +#include "expr-plus.h" +#include "object-string.h" +#include "filterx-eval.h" +#include "scratch-buffers.h" + +typedef struct FilterXOperatorPlus +{ + FilterXBinaryOp super; +} FilterXOperatorPlus; + +static FilterXObject * +_eval(FilterXExpr *s) +{ + FilterXOperatorPlus *self = (FilterXOperatorPlus *) s; + + FilterXObject *lhs_object = filterx_expr_eval(self->super.lhs); + if (!lhs_object) + { + return NULL; + } + + FilterXObject *rhs_object = filterx_expr_eval(self->super.rhs); + if (!rhs_object) + { + filterx_object_unref(lhs_object); + return NULL; + } + + if (filterx_object_is_type(lhs_object, &FILTERX_TYPE_NAME(string)) && + filterx_object_is_type(rhs_object, &FILTERX_TYPE_NAME(string))) + { + gsize lhs_len, rhs_len; + const gchar *lhs_value = filterx_string_get_value(lhs_object, &lhs_len); + const gchar *rhs_value = filterx_string_get_value(rhs_object, &rhs_len); + GString *buffer = scratch_buffers_alloc(); + + g_string_append_len(buffer, lhs_value, lhs_len); + g_string_append_len(buffer, rhs_value, rhs_len); + /* FIXME: support taking over the already allocated space */ + return filterx_string_new(buffer->str, buffer->len); + } + + filterx_eval_push_error("operator+ only works on strings", s, NULL); + filterx_object_unref(lhs_object); + filterx_object_unref(rhs_object); + return NULL; +} + +FilterXExpr * +filterx_operator_plus_new(FilterXExpr *lhs, FilterXExpr *rhs) +{ + FilterXOperatorPlus *self = g_new0(FilterXOperatorPlus, 1); + filterx_binary_op_init_instance(&self->super, lhs, rhs); + self->super.super.eval = _eval; + return &self->super.super; +} diff --git a/lib/filterx/expr-plus.h b/lib/filterx/expr-plus.h new file mode 100644 index 0000000000..2a10e8117f --- /dev/null +++ b/lib/filterx/expr-plus.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Balazs Scheidler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ +#ifndef FILTERX_EXPR_PLUS_H_INCLUDED +#define FILTERX_EXPR_PLUS_H_INCLUDED + +#include "filterx-expr.h" + +FilterXExpr *filterx_operator_plus_new(FilterXExpr *lhs, FilterXExpr *rhs); + +#endif diff --git a/lib/filterx/filterx-grammar.ym b/lib/filterx/filterx-grammar.ym index d0f6bf136a..0d41f392f6 100644 --- a/lib/filterx/filterx-grammar.ym +++ b/lib/filterx/filterx-grammar.ym @@ -52,6 +52,7 @@ #include "filterx/expr-literal-generator.h" #include "filterx/expr-shorthand.h" #include "filterx/expr-regexp.h" +#include "filterx/expr-plus.h" #include "template/templates.h" @@ -299,6 +300,7 @@ expr | expr KW_STR_GT expr { $$ = filterx_comparison_new($1, $3, FCMPX_STRING_BASED | FCMPX_GT); } | expr KW_TAV_EQ expr { $$ = filterx_comparison_new($1, $3, FCMPX_TYPE_AND_VALUE_BASED | FCMPX_EQ); } | expr KW_TAV_NE expr { $$ = filterx_comparison_new($1, $3, FCMPX_TYPE_AND_VALUE_BASED | FCMPX_NE ); } + | expr '+' expr { $$ = filterx_operator_plus_new($1, $3); } | '(' expr ')' { $$ = $2; } | ternary { $$ = $1; } | KW_ISSET '(' expr ')' { $$ = filterx_isset_new($3); }