From 4e3330eb989eac513b5c467c90c374edeca65767 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 5 Sep 2023 09:51:25 +0200 Subject: [PATCH] libsmartcols: (filter) split code Signed-off-by: Karel Zak --- libsmartcols/src/Makemodule.am | 5 +- libsmartcols/src/filter-expr.c | 87 ++++++++++++++ libsmartcols/src/filter-param.c | 102 +++++++++++++++++ libsmartcols/src/filter.c | 197 ++------------------------------ libsmartcols/src/smartcolsP.h | 18 +++ 5 files changed, 219 insertions(+), 190 deletions(-) create mode 100644 libsmartcols/src/filter-expr.c create mode 100644 libsmartcols/src/filter-param.c diff --git a/libsmartcols/src/Makemodule.am b/libsmartcols/src/Makemodule.am index 4c373358fc..d8077e0554 100644 --- a/libsmartcols/src/Makemodule.am +++ b/libsmartcols/src/Makemodule.am @@ -26,7 +26,10 @@ libsmartcols_la_SOURCES= \ libsmartcols/src/filter-scanner.l \ libsmartcols/src/filter-parser.h \ libsmartcols/src/filter-scanner.h \ - libsmartcols/src/filter.c + \ + libsmartcols/src/filter.c \ + libsmartcols/src/filter-param.c \ + libsmartcols/src/filter-expr.c BUILT_SOURCES += libsmartcols/src/filter-parser.c \ libsmartcols/src/filter-scanner.c diff --git a/libsmartcols/src/filter-expr.c b/libsmartcols/src/filter-expr.c new file mode 100644 index 0000000000..e34365d165 --- /dev/null +++ b/libsmartcols/src/filter-expr.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include "smartcolsP.h" + +struct filter_node *filter_new_expr( + struct libscols_filter *fltr __attribute__((__unused__)), + enum filter_etype type, + struct filter_node *left, + struct filter_node *right) +{ + struct filter_expr *n = (struct filter_expr *) __filter_new_node( + F_NODE_EXPR, sizeof(struct filter_expr)); + + n->type = type; + switch (type) { + case F_EXPR_AND: + case F_EXPR_OR: + case F_EXPR_EQ: + case F_EXPR_NE: + case F_EXPR_LE: + case F_EXPR_LT: + case F_EXPR_GE: + case F_EXPR_GT: + case F_EXPR_REG: + case F_EXPR_NREG: + n->left = left; + n->right = right; + break; + case F_EXPR_NEG: + n->right = right; + break; + + } + return (struct filter_node *) n; +} + +void filter_free_expr(struct filter_expr *n) +{ + filter_unref_node(n->left); + filter_unref_node(n->right); + free(n); +} + +static const char *expr_type_as_string(struct filter_expr *n) +{ + switch (n->type) { + case F_EXPR_AND: + return "AND"; + case F_EXPR_OR: + return "OR"; + case F_EXPR_EQ: + return "EQ"; + case F_EXPR_NE: + return "NE"; + case F_EXPR_LE: + return "LE"; + case F_EXPR_LT: + return "LT"; + case F_EXPR_GE: + return "GE"; + case F_EXPR_GT: + return "GT"; + case F_EXPR_REG: + return "REG"; + case F_EXPR_NREG: + return "NREG"; + case F_EXPR_NEG: + return "NOT"; + } + return ""; +} + +void filter_dump_expr(struct ul_jsonwrt *json, struct filter_expr *n) +{ + ul_jsonwrt_object_open(json, "expr"); + ul_jsonwrt_value_s(json, "type", expr_type_as_string(n)); + + if (n->left) + filter_dump_node(json, n->left); + if (n->right) + filter_dump_node(json, n->right); + + ul_jsonwrt_object_close(json); +} diff --git a/libsmartcols/src/filter-param.c b/libsmartcols/src/filter-param.c new file mode 100644 index 0000000000..cec98691de --- /dev/null +++ b/libsmartcols/src/filter-param.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#include "smartcolsP.h" + +struct filter_node *filter_new_param( + struct libscols_filter *fltr, + enum filter_ptype type, + void *data) +{ + char *p; + struct filter_param *n = (struct filter_param *) __filter_new_node( + F_NODE_PARAM, + sizeof(struct filter_param)); + n->type = type; + INIT_LIST_HEAD(&n->pr_params); + + switch (type) { + case F_PARAM_STRING: + p = data; + if (*p == '"') { + /* remove quotation marks */ + size_t len = strlen(p); + if (*(p + (len - 1)) == '"') + *(p + (len - 1)) = '\0'; + data = p + 1; + } + /* fallthrough */ + case F_PARAM_NAME: + n->val.str = strdup((char *) data); + break; + case F_PARAM_NUMBER: + n->val.num = *((unsigned long long *) data); + break; + case F_PARAM_FLOAT: + n->val.fnum = *((long double *) data); + break; + case F_PARAM_BOOLEAN: + n->val.boolean = *((bool *) data) == 0 ? 0 : 1; + break; + } + + list_add_tail(&n->pr_params, &fltr->params); + + return (struct filter_node *) n; +} + +void filter_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); +} + +void filter_dump_param(struct ul_jsonwrt *json, struct filter_param *n) +{ + ul_jsonwrt_object_open(json, "param"); + + switch (n->type) { + case F_PARAM_NAME: + ul_jsonwrt_value_s(json, "name", n->val.str); + break; + case F_PARAM_STRING: + ul_jsonwrt_value_s(json, "string", n->val.str); + break; + case F_PARAM_NUMBER: + ul_jsonwrt_value_u64(json, "number", n->val.num); + break; + case F_PARAM_FLOAT: + ul_jsonwrt_value_double(json, "float", n->val.fnum); + break; + case F_PARAM_BOOLEAN: + ul_jsonwrt_value_boolean(json, "bool", n->val.boolean); + break; + } + ul_jsonwrt_object_close(json); +} + +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; +} + diff --git a/libsmartcols/src/filter.c b/libsmartcols/src/filter.c index 025b672010..e960ba66d2 100644 --- a/libsmartcols/src/filter.c +++ b/libsmartcols/src/filter.c @@ -8,9 +8,6 @@ #include "filter-parser.h" #include "filter-scanner.h" -static void filter_unref_node(struct filter_node *n); -static void filter_dump_node(struct ul_jsonwrt *json, struct filter_node *n); - struct libscols_filter *scols_new_filter(const char *str) { struct libscols_filter *fltr = calloc(1, sizeof(*fltr)); @@ -60,7 +57,7 @@ void scols_unref_filter(struct libscols_filter *fltr) /* This is generic allocater for a new node, always use the node type specific * functions (e.g. filter_new_param() */ -static struct filter_node *new_node(enum filter_ntype type, size_t sz) +struct filter_node *__filter_new_node(enum filter_ntype type, size_t sz) { void *x = calloc(1, sz); struct filter_node *n = (struct filter_node *) x; @@ -73,197 +70,38 @@ static struct filter_node *new_node(enum filter_ntype type, size_t sz) return n; } -struct filter_node *filter_new_param( - struct libscols_filter *fltr, - enum filter_ptype type, - void *data) -{ - char *p; - struct filter_param *n = (struct filter_param *) new_node( - F_NODE_PARAM, - sizeof(struct filter_param)); - n->type = type; - INIT_LIST_HEAD(&n->pr_params); - - switch (type) { - case F_PARAM_STRING: - p = data; - if (*p == '"') { - /* remove quotation marks */ - size_t len = strlen(p); - if (*(p + (len - 1)) == '"') - *(p + (len - 1)) = '\0'; - data = p + 1; - } - /* fallthrough */ - case F_PARAM_NAME: - n->val.str = strdup((char *) data); - break; - case F_PARAM_NUMBER: - n->val.num = *((unsigned long long *) data); - break; - case F_PARAM_FLOAT: - n->val.fnum = *((long double *) data); - break; - case F_PARAM_BOOLEAN: - n->val.boolean = *((bool *) data) == 0 ? 0 : 1; - break; - } - - list_add_tail(&n->pr_params, &fltr->params); - - return (struct filter_node *) n; -} - -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); -} - -static void dump_param(struct ul_jsonwrt *json, struct filter_param *n) -{ - ul_jsonwrt_object_open(json, "param"); - - switch (n->type) { - case F_PARAM_NAME: - ul_jsonwrt_value_s(json, "name", n->val.str); - break; - case F_PARAM_STRING: - ul_jsonwrt_value_s(json, "string", n->val.str); - break; - case F_PARAM_NUMBER: - ul_jsonwrt_value_u64(json, "number", n->val.num); - break; - case F_PARAM_FLOAT: - ul_jsonwrt_value_double(json, "float", n->val.fnum); - break; - case F_PARAM_BOOLEAN: - ul_jsonwrt_value_boolean(json, "bool", n->val.boolean); - break; - } - ul_jsonwrt_object_close(json); -} - -struct filter_node *filter_new_expr( - struct libscols_filter *fltr __attribute__((__unused__)), - enum filter_etype type, - struct filter_node *left, - struct filter_node *right) -{ - struct filter_expr *n = (struct filter_expr *) new_node( - F_NODE_EXPR, sizeof(struct filter_expr)); - - n->type = type; - switch (type) { - case F_EXPR_AND: - case F_EXPR_OR: - case F_EXPR_EQ: - case F_EXPR_NE: - case F_EXPR_LE: - case F_EXPR_LT: - case F_EXPR_GE: - case F_EXPR_GT: - case F_EXPR_REG: - case F_EXPR_NREG: - n->left = left; - n->right = right; - break; - case F_EXPR_NEG: - n->right = right; - break; - - } - return (struct filter_node *) n; -} - -static void free_expr(struct filter_expr *n) -{ - filter_unref_node(n->left); - filter_unref_node(n->right); - free(n); -} - -static const char *expr_type_as_string(struct filter_expr *n) -{ - switch (n->type) { - case F_EXPR_AND: - return "AND"; - case F_EXPR_OR: - return "OR"; - case F_EXPR_EQ: - return "EQ"; - case F_EXPR_NE: - return "NE"; - case F_EXPR_LE: - return "LE"; - case F_EXPR_LT: - return "LT"; - case F_EXPR_GE: - return "GE"; - case F_EXPR_GT: - return "GT"; - case F_EXPR_REG: - return "REG"; - case F_EXPR_NREG: - return "NREG"; - case F_EXPR_NEG: - return "NOT"; - } - return ""; -} - -static void dump_expr(struct ul_jsonwrt *json, struct filter_expr *n) -{ - ul_jsonwrt_object_open(json, "expr"); - ul_jsonwrt_value_s(json, "type", expr_type_as_string(n)); - - if (n->left) - filter_dump_node(json, n->left); - if (n->right) - filter_dump_node(json, n->right); - - ul_jsonwrt_object_close(json); -} - -static void filter_unref_node(struct filter_node *n) +void filter_unref_node(struct filter_node *n) { if (!n || --n->refcount > 0) return; switch (n->type) { case F_NODE_EXPR: - free_expr((struct filter_expr *) n); + filter_free_expr((struct filter_expr *) n); break; case F_NODE_PARAM: - free_param((struct filter_param *) n); + filter_free_param((struct filter_param *) n); break; } } -/* -static void filter_ref_node(struct filter_node *n) +void filter_ref_node(struct filter_node *n) { if (n) n->refcount++; } -*/ -static void filter_dump_node(struct ul_jsonwrt *json, struct filter_node *n) +void filter_dump_node(struct ul_jsonwrt *json, struct filter_node *n) { if (!n) return; switch (n->type) { case F_NODE_EXPR: - dump_expr(json, (struct filter_expr *) n); + filter_dump_expr(json, (struct filter_expr *) n); break; case F_NODE_PARAM: - dump_param(json, (struct filter_param *) n); + filter_dump_param(json, (struct filter_param *) n); break; } } @@ -315,25 +153,6 @@ 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) { diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h index 15d6fc62d1..0119cedfd5 100644 --- a/libsmartcols/src/smartcolsP.h +++ b/libsmartcols/src/smartcolsP.h @@ -554,6 +554,24 @@ struct libscols_filter { struct list_head params; }; +struct filter_node *__filter_new_node(enum filter_ntype type, size_t sz); +void filter_ref_node(struct filter_node *n); +void filter_unref_node(struct filter_node *n); + +void filter_dump_node(struct ul_jsonwrt *json, struct filter_node *n); + +/* param */ +void filter_dump_param(struct ul_jsonwrt *json, struct filter_param *n); +void filter_free_param(struct filter_param *n); + +int filter_next_param(struct libscols_filter *fltr, + struct libscols_iter *itr, struct filter_param **prm); + +/* expr */ +void filter_free_expr(struct filter_expr *n); +void filter_dump_expr(struct ul_jsonwrt *json, struct filter_expr *n); + + /* required by parser */ struct filter_node *filter_new_param(struct libscols_filter *filter, enum filter_ptype type, -- 2.47.3