]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols (filter) fetch data from columns
authorKarel Zak <kzak@redhat.com>
Tue, 5 Sep 2023 11:43:37 +0000 (13:43 +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/samples/filter.c
libsmartcols/src/filter-param.c
libsmartcols/src/filter.c
libsmartcols/src/smartcolsP.h

index ec61b7f00ef561efb44bb3fd53cb091481032023..5be95e49603e0f87ca9c80fd2c7b79e406da6162 100644 (file)
@@ -170,6 +170,9 @@ int main(int argc, char *argv[])
 
        scols_print_table(tb);
 done:
+       if (dump && fltr)
+               scols_dump_filter(fltr, stdout);
+
        scols_unref_table(tb);
        scols_unref_filter(fltr);
        scols_free_iter(itr);
index 36b906be4b590b55b498332def1b5596629234e4..0aa646484432235d089fd1aae1212e3dbfcf4001 100644 (file)
@@ -23,23 +23,22 @@ static int param_set_data(struct filter_param *n, enum filter_data type, const v
                        n->val.str = strdup((char *) data);
                if (!n->val.str)
                        return -ENOMEM;
-               n->has_value = 1;
                break;
        case F_DATA_NUMBER:
                n->val.num = *((unsigned long long *) data);
-               n->has_value = 1;
                break;
        case F_DATA_FLOAT:
                n->val.fnum = *((long double *) data);
-               n->has_value = 1;
                break;
        case F_DATA_BOOLEAN:
                n->val.boolean = *((bool *) data) == 0 ? 0 : 1;
-               n->has_value = 1;
                break;
        default:
-               break;
+               return 0;
        }
+
+       n->type = type;
+       n->has_value = 1;
        return 0;
 }
 
@@ -61,7 +60,8 @@ struct filter_node *filter_new_param(
 
        switch (holder) {
        case F_HOLDER_COLUMN:
-               n->val.str = strdup((char *) data);
+               n->holder_name = strdup((char *) data);
+               DBG(FLTR, ul_debugobj(fltr, "new %s holder", n->holder_name));
                break;
        default:
                break;
@@ -72,11 +72,21 @@ struct filter_node *filter_new_param(
        return (struct filter_node *) n;
 }
 
-void filter_free_param(struct filter_param *n)
+static void param_reset_data(struct filter_param *n)
 {
-       if (n->type == F_DATA_STRING || n->holder == F_HOLDER_COLUMN)
+       if (n->type == F_DATA_STRING)
                free(n->val.str);
 
+       memset(&n->val, 0, sizeof(n->val));
+       n->has_value = 0;
+}
+
+
+void filter_free_param(struct filter_param *n)
+{
+       param_reset_data(n);
+
+       free(n->holder_name);
        list_del_init(&n->pr_params);
        scols_unref_column(n->col);
        free(n);
@@ -115,7 +125,7 @@ void filter_dump_param(struct ul_jsonwrt *json, struct filter_param *n)
 
        switch (n->holder) {
        case F_HOLDER_COLUMN:
-               ul_jsonwrt_value_s(json, "column", n->val.str);
+               ul_jsonwrt_value_s(json, "column", n->holder_name);
                break;
        default:
                break;
@@ -124,14 +134,42 @@ void filter_dump_param(struct ul_jsonwrt *json, struct filter_param *n)
        ul_jsonwrt_object_close(json);
 }
 
-int filter_eval_param(struct libscols_filter *fltr  __attribute__((__unused__)),
+static int fetch_holder_data(struct libscols_filter *fltr,
+                       struct filter_param *n, struct libscols_line *ln)
+{
+       const char *data;
+       int rc;
+
+       if (n->holder != F_HOLDER_COLUMN)
+               return 0;
+       if (!n->col) {
+               DBG(FLTR, ul_debugobj(fltr, "no column for %s holder", n->holder_name));
+               return -EINVAL;
+       }
+
+       DBG(FLTR, ul_debugobj(fltr, "fetching %s data", n->holder_name));
+
+       param_reset_data(n);
+
+       data = scols_line_get_column_data(ln, n->col);
+       rc = param_set_data(n, F_DATA_STRING, data);
+
+       return rc;
+}
+
+int filter_eval_param(struct libscols_filter *fltr,
                struct filter_param *n,
-               struct libscols_line *ln  __attribute__((__unused__)),
+               struct libscols_line *ln,
                int *status)
 {
        int rc = 0;
 
-       if (!n->has_value) {
+       DBG(FLTR, ul_debugobj(fltr, "eval param"));
+
+       if (!n->has_value && n->holder)
+               rc = fetch_holder_data(fltr, n, ln);
+
+       if (!n->has_value || rc) {
                *status = 0;
                goto done;
        }
@@ -154,6 +192,8 @@ int filter_eval_param(struct libscols_filter *fltr  __attribute__((__unused__)),
                break;
        }
 done:
+       if (rc)
+               DBG(FLTR, ul_debugobj(fltr, "failed eval param [rc=%d]", rc));
        return rc;
 }
 
index e99e79fc6927665b92ea397700a53bf8efc7b4d8..99201a3a8ce2598324f4199711014097ae19deb5 100644 (file)
@@ -168,7 +168,7 @@ int scols_filter_next_holder(struct libscols_filter *fltr,
        do {
                rc = filter_next_param(fltr, itr, &prm);
                if (rc == 0 && (int) prm->holder == type) {
-                       *name = prm->val.str;
+                       *name = prm->holder_name;
                }
        } while (rc == 0 && !*name);
 
@@ -184,7 +184,7 @@ int scols_filter_assign_column(struct libscols_filter *fltr,
 
        scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
        while (filter_next_param(fltr, &itr, &prm) == 0) {
-               if (prm->holder != F_HOLDER_COLUMN || strcmp(name, prm->val.str) != 0)
+               if (prm->holder != F_HOLDER_COLUMN || strcmp(name, prm->holder_name) != 0)
                        continue;
                prm->col = col;
                scols_ref_column(col);
@@ -211,8 +211,12 @@ int filter_eval_node(struct libscols_filter *fltr, struct filter_node *n,
 int scols_line_apply_filter(struct libscols_line *ln,
                        struct libscols_filter *fltr, int *status)
 {
+       int rc;
        if (!ln || !fltr || !fltr->root)
                return -EINVAL;
 
-       return filter_eval_node(fltr, fltr->root, ln, status);
+       rc = filter_eval_node(fltr, fltr->root, ln, status);
+
+       DBG(FLTR, ul_debugobj(fltr, "filter applid [rc=%d, status=%d]", rc, *status));
+       return rc;
 }
index bca884fc3e0f02fc0683d87e8a0ffb8bb1b9e4f7..e762e081eae122fc1d049e667f0e786f9d97bc4d 100644 (file)
@@ -540,6 +540,7 @@ struct filter_param {
 
        struct list_head pr_params;
        struct libscols_column *col;
+       char *holder_name;
 
        unsigned int has_value :1;
 };