]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: (filter) implement data basic operators
authorKarel Zak <kzak@redhat.com>
Thu, 7 Sep 2023 08:24:03 +0000 (10:24 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 20 Nov 2023 21:25:46 +0000 (22:25 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/src/filter-expr.c
libsmartcols/src/filter-param.c
libsmartcols/src/smartcolsP.h

index f782e2d2be20a9ab8e7b40321605efb52090c609..9ea4e6b7beea172892454ee8ab9370a0e0dd176a 100644 (file)
@@ -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;
 }
index 0aa646484432235d089fd1aae1212e3dbfcf4001..7acd021febff89db3694b1f1e02a3b4ad3a31764 100644 (file)
@@ -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)
 {
index e762e081eae122fc1d049e667f0e786f9d97bc4d..94d4f996b9519df84286da7199a982f64e6c8186 100644 (file)
@@ -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);