]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: add API to join filter and columns
authorKarel Zak <kzak@redhat.com>
Thu, 31 Aug 2023 15:41:04 +0000 (17:41 +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.c
libsmartcols/src/libsmartcols.h.in
libsmartcols/src/libsmartcols.sym
libsmartcols/src/smartcolsP.h

index e043e46acfd79cbcab22bf7746a314de8b82ed66..aaf7fb69eaf72da5afb6c0b46260448d6f68043c 100644 (file)
@@ -86,7 +86,9 @@ int main(int argc, char *argv[])
 {
        struct libscols_table *tb;
        struct libscols_filter *fltr = NULL;
+       struct libscols_iter *itr = NULL;
        int c, i, json = 0, dump = 0;
+       int rc = 0;
 
        static const struct option longopts[] = {
                { "json",   0, NULL, 'J' },
@@ -132,11 +134,34 @@ int main(int argc, char *argv[])
        scols_table_enable_json(tb, json);
        setup_columns(tb);
 
+       if (fltr) {
+               const char *name = NULL;
+
+               itr = scols_new_iter(SCOLS_ITER_FORWARD);
+               if (!itr)
+                       err(EXIT_FAILURE, "failed to allocate iterator");
+
+               while (scols_filter_next_name(fltr, itr, &name) == 0) {
+                       struct libscols_column *col =
+                                       scols_table_get_column_by_name(tb, name);
+                       if (!col) {
+                               warnx("unknown column '%s' in filter", name);
+                               rc++;
+                               continue;
+                       }
+                       scols_filter_assign_column(fltr, name, col);
+               }
+               if (rc)
+                       goto done;
+       }
+
        for (i = 0; i < 10; i++)
                add_line(tb, i + 1);
 
        scols_print_table(tb);
+done:
        scols_unref_table(tb);
        scols_unref_filter(fltr);
-       return EXIT_SUCCESS;
+       scols_free_iter(itr);
+       return rc ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 30d601a686806e248c64279bc097af26c25d2da6..025b672010d6787556a5fb5e2e98c9b3d17f5896 100644 (file)
@@ -18,6 +18,7 @@ struct libscols_filter *scols_new_filter(const char *str)
        if (!fltr)
                return NULL;
        fltr->refcount = 1;
+       INIT_LIST_HEAD(&fltr->params);
 
        if (str && scols_filter_parse_string(fltr, str) != 0) {
                scols_unref_filter(fltr);
@@ -73,7 +74,7 @@ static struct filter_node *new_node(enum filter_ntype type, size_t sz)
 }
 
 struct filter_node *filter_new_param(
-               struct libscols_filter *fltr __attribute__((__unused__)),
+               struct libscols_filter *fltr,
                enum filter_ptype type,
                void *data)
 {
@@ -82,6 +83,7 @@ struct filter_node *filter_new_param(
                                        F_NODE_PARAM,
                                        sizeof(struct filter_param));
        n->type = type;
+       INIT_LIST_HEAD(&n->pr_params);
 
        switch (type) {
        case F_PARAM_STRING:
@@ -107,6 +109,9 @@ struct filter_node *filter_new_param(
                n->val.boolean = *((bool *) data) == 0 ? 0 : 1;
                break;
        }
+
+       list_add_tail(&n->pr_params, &fltr->params);
+
        return (struct filter_node *) n;
 }
 
@@ -114,6 +119,9 @@ static void free_param(struct filter_param *n)
 {
        if (n->type == F_PARAM_NAME || n->type == F_PARAM_STRING)
                free(n->val.str);
+
+       list_del_init(&n->pr_params);
+       scols_unref_column(n->col);
        free(n);
 }
 
@@ -260,6 +268,8 @@ static void filter_dump_node(struct ul_jsonwrt *json, struct filter_node *n)
        }
 }
 
+
+
 extern int yyparse(void *scanner, struct libscols_filter *fltr);
 
 int scols_filter_parse_string(struct libscols_filter *fltr, const char *str)
@@ -304,3 +314,58 @@ const char *scols_filter_get_errmsg(struct libscols_filter *fltr)
 {
        return fltr ? fltr->errmsg : NULL;
 }
+
+static int filter_next_param(struct libscols_filter *fltr,
+                       struct libscols_iter *itr, struct filter_param **prm)
+{
+       int rc = 1;
+
+       if (!fltr || !itr || !prm)
+               return -EINVAL;
+       *prm = NULL;
+
+       if (!itr->head)
+               SCOLS_ITER_INIT(itr, &fltr->params);
+       if (itr->p != itr->head) {
+               SCOLS_ITER_ITERATE(itr, *prm, struct filter_param, pr_params);
+               rc = 0;
+       }
+
+       return rc;
+}
+
+int scols_filter_next_name(struct libscols_filter *fltr,
+                       struct libscols_iter *itr, const char **name)
+{
+       struct filter_param *prm = NULL;
+       int rc = 0;
+
+       *name = NULL;
+
+       do {
+               rc = filter_next_param(fltr, itr, &prm);
+               if (rc == 0 && prm->type == F_PARAM_NAME)
+                       *name = prm->val.str;
+       } while (rc == 0 && !*name);
+
+       return rc;
+}
+
+int scols_filter_assign_column(struct libscols_filter *fltr,
+                       const char *name, struct libscols_column *col)
+{
+       struct libscols_iter itr;
+       struct filter_param *prm = NULL;
+       int ct = 0;
+
+       scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
+       while (filter_next_param(fltr, &itr, &prm) == 0) {
+               if (prm->type != F_PARAM_NAME || strcmp(name, prm->val.str) != 0)
+                       continue;
+               prm->col = col;
+               scols_ref_column(col);
+               ct++;
+       }
+
+       return ct == 0 ? 1 : 0;
+}
index 2262cb149cbf76dfea60ac305352173ffbee3548..bb23e1f08b5d0f3e00d278ef79e712cc79149723 100644 (file)
@@ -374,6 +374,11 @@ extern void scols_unref_filter(struct libscols_filter *fltr);
 extern int scols_dump_filter(struct libscols_filter *fltr, FILE *out);
 extern const char *scols_filter_get_errmsg(struct libscols_filter *fltr);
 
+extern int scols_filter_next_name(struct libscols_filter *fltr,
+                        struct libscols_iter *itr, const char **name);
+extern int scols_filter_assign_column(struct libscols_filter *fltr,
+                        const char *name, struct libscols_column *col);
+
 #ifdef __cplusplus
 }
 #endif
index 4fb97f43e7c4fe367dfd65afe62abbd129086274..b50c80d79b17fdc46759bcb5a76df62b41362e5d 100644 (file)
@@ -226,4 +226,6 @@ SMARTCOLS_2.40 {
        scols_new_filter;
        scols_unref_filter;
        scols_filter_get_errmsg;
+       scols_filter_next_name;
+       scols_filter_assign_column;
 } SMARTCOLS_2.39;
index 86c07ea40e783f1ad4af6ddbe908a6a68f727242..15d6fc62d17e200ec6b10692210425a0fe0ed24b 100644 (file)
@@ -532,6 +532,9 @@ struct filter_param {
                long double fnum;
                bool boolean;
        } val;
+
+       struct list_head pr_params;
+       struct libscols_column *col;
 };
 
 struct filter_expr {
@@ -547,6 +550,8 @@ struct libscols_filter {
        char *errmsg;
        struct filter_node *root;
        FILE *src;
+
+       struct list_head params;
 };
 
 /* required by parser */