From: Karel Zak Date: Thu, 7 Sep 2023 08:24:03 +0000 (+0200) Subject: libsmartcols: (filter) implement data basic operators X-Git-Tag: v2.40-rc1~151^2~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a4183e588cbaa145e97edb0ed3e354972309566;p=thirdparty%2Futil-linux.git libsmartcols: (filter) implement data basic operators Signed-off-by: Karel Zak --- diff --git a/libsmartcols/src/filter-expr.c b/libsmartcols/src/filter-expr.c index f782e2d2be..9ea4e6b7be 100644 --- a/libsmartcols/src/filter-expr.c +++ b/libsmartcols/src/filter-expr.c @@ -91,6 +91,7 @@ int filter_eval_expr(struct libscols_filter *fltr, struct filter_expr *n, struct libscols_line *ln, int *status) { int rc = 0; + struct filter_param *l = NULL, *r = NULL; enum filter_etype oper = n->type; /* logical operators */ @@ -114,5 +115,10 @@ int filter_eval_expr(struct libscols_filter *fltr, struct filter_expr *n, break; } + /* compare data */ + l = (struct filter_param *) n->left; + r = (struct filter_param *) n->right; + rc = filter_compare_params(fltr, ln, oper, l, r, status); + return rc; } diff --git a/libsmartcols/src/filter-param.c b/libsmartcols/src/filter-param.c index 0aa6464844..7acd021feb 100644 --- a/libsmartcols/src/filter-param.c +++ b/libsmartcols/src/filter-param.c @@ -197,6 +197,153 @@ done: return rc; } +static int string_opers(enum filter_etype oper, struct filter_param *l, + struct filter_param *r, int *status) +{ + switch (oper) { + case F_EXPR_EQ: + *status = strcmp(l->val.str, r->val.str) == 0; + break; + case F_EXPR_NE: + *status = strcmp(l->val.str, r->val.str) != 0; + break; + case F_EXPR_LE: + *status = strcmp(l->val.str, r->val.str) <= 0; + break; + case F_EXPR_LT: + *status = strcmp(l->val.str, r->val.str) < 0; + break; + case F_EXPR_GE: + *status = strcmp(l->val.str, r->val.str) >= 0; + break; + case F_EXPR_GT: + *status = strcmp(l->val.str, r->val.str) > 0; + break; + default: + return -EINVAL; + } + return 0; +} + +static int number_opers(enum filter_etype oper, struct filter_param *l, + struct filter_param *r, int *status) +{ + switch (oper) { + case F_EXPR_EQ: + *status = l->val.num == r->val.num; + break; + case F_EXPR_NE: + *status = l->val.num != r->val.num; + break; + case F_EXPR_LE: + *status = l->val.num <= r->val.num; + break; + case F_EXPR_LT: + *status = l->val.num < r->val.num; + break; + case F_EXPR_GE: + *status = l->val.num >= r->val.num; + break; + case F_EXPR_GT: + *status = l->val.num > r->val.num; + break; + default: + return -EINVAL; + } + return 0; +} + +static int float_opers(enum filter_etype oper, struct filter_param *l, + struct filter_param *r, int *status) +{ + switch (oper) { + case F_EXPR_EQ: + *status = l->val.fnum == r->val.fnum; + break; + case F_EXPR_NE: + *status = l->val.fnum != r->val.fnum; + break; + case F_EXPR_LE: + *status = l->val.fnum <= r->val.fnum; + break; + case F_EXPR_LT: + *status = l->val.fnum < r->val.fnum; + break; + case F_EXPR_GE: + *status = l->val.fnum >= r->val.fnum; + break; + case F_EXPR_GT: + *status = l->val.fnum > r->val.fnum; + break; + default: + return -EINVAL; + } + return 0; +} + +static int bool_opers(enum filter_etype oper, struct filter_param *l, + struct filter_param *r, int *status) +{ + switch (oper) { + case F_EXPR_EQ: + *status = l->val.boolean == r->val.boolean; + break; + case F_EXPR_NE: + *status = l->val.boolean != r->val.boolean; + break; + case F_EXPR_LE: + *status = l->val.boolean <= r->val.boolean; + break; + case F_EXPR_LT: + *status = l->val.boolean < r->val.boolean; + break; + case F_EXPR_GE: + *status = l->val.boolean >= r->val.boolean; + break; + case F_EXPR_GT: + *status = l->val.boolean > r->val.boolean; + break; + default: + return -EINVAL; + } + return 0; +} + +int filter_compare_params(struct libscols_filter *fltr __attribute__((__unused__)), + struct libscols_line *ln __attribute__((__unused__)), + enum filter_etype oper, + struct filter_param *l, + struct filter_param *r, + int *status) +{ + int rc; + + if (!l || !r || l->type != r->type) + return -EINVAL; + + *status = 0; + + switch (l->type) { + case F_DATA_STRING: + rc = string_opers(oper, l, r, status); + break; + case F_DATA_NUMBER: + rc = number_opers(oper, l, r, status); + break; + case F_DATA_FLOAT: + rc = float_opers(oper, l, r, status); + break; + case F_DATA_BOOLEAN: + rc = bool_opers(oper, l, r, status); + break; + default: + rc = -EINVAL; + break; + } + + return rc; +} + int filter_next_param(struct libscols_filter *fltr, struct libscols_iter *itr, struct filter_param **prm) { diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h index e762e081ea..94d4f996b9 100644 --- a/libsmartcols/src/smartcolsP.h +++ b/libsmartcols/src/smartcolsP.h @@ -579,6 +579,13 @@ void filter_free_param(struct filter_param *n); int filter_next_param(struct libscols_filter *fltr, struct libscols_iter *itr, struct filter_param **prm); +int filter_compare_params(struct libscols_filter *fltr, + struct libscols_line *ln, + enum filter_etype oper, + struct filter_param *l, + struct filter_param *r, + int *status); + /* expr */ void filter_free_expr(struct filter_expr *n); void filter_dump_expr(struct ul_jsonwrt *json, struct filter_expr *n);