]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: improve filter integration, use JSON to dump
authorKarel Zak <kzak@redhat.com>
Tue, 8 Aug 2023 10:18:56 +0000 (12:18 +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/Makemodule.am
libsmartcols/src/filter-nodes.c [deleted file]
libsmartcols/src/filter-parser.y
libsmartcols/src/filter-scanner.l
libsmartcols/src/filter.c
libsmartcols/src/init.c
libsmartcols/src/libsmartcols.h.in
libsmartcols/src/libsmartcols.sym
libsmartcols/src/smartcolsP.h

index 51458cbfc2cdea1ba778e10f4ffde20264c5cdb2..4c373358fc9b82628d87631c1e9ff80d1a581bd7 100644 (file)
@@ -22,16 +22,25 @@ libsmartcols_la_SOURCES= \
        libsmartcols/src/walk.c \
        libsmartcols/src/init.c \
        \
-       libsmartcols/src/filter-nodes.c \
        libsmartcols/src/filter-parser.y \
        libsmartcols/src/filter-scanner.l \
+       libsmartcols/src/filter-parser.h \
+       libsmartcols/src/filter-scanner.h \
        libsmartcols/src/filter.c
 
-BUILT_SOURCES = libsmartcols/src/filter-scanner.c \
-               libsmartcols/src/filter-scanner.h \
-               libsmartcols/src/filter-parser.h \
-               libsmartcols/src/filter-parser.c
-AM_YFLAGS = -d
+BUILT_SOURCES += libsmartcols/src/filter-parser.c \
+                libsmartcols/src/filter-scanner.c
+
+
+# Scanner and parser header files are maintained in git and generated
+# manually by only if necessary.
+#
+libsmartcols/src/filter-scanner.h: libsmartcols/src/filter-scanner.l
+       $(AM_V_LEX) $(LEX) --header-file=$@ $<
+
+libsmartcols/src/filter-parser.h: libsmartcols/src/filter-parser.y
+       $(AM_V_YACC) $(YACC) --header=$@ $<
+
 
 libsmartcols_la_LIBADD = $(LDADD) libcommon.la
 
diff --git a/libsmartcols/src/filter-nodes.c b/libsmartcols/src/filter-nodes.c
deleted file mode 100644 (file)
index fadb364..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-
-#include "smartcolsP.h"
-
-/* 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)
-{
-       void *x = calloc(1, sz);
-       struct filter_node *n = (struct filter_node *) x;
-
-       if (!x)
-               return NULL;
-
-       n->type = type;
-       n->refcount = 1;
-       return n;
-}
-
-struct filter_node *filter_new_param(struct libscols_filter *fltr __attribute__((__unused__)),
-                                enum filter_ptype type,
-                                void *data)
-{
-       struct filter_param *n = (struct filter_param *) new_node(
-                                       F_NODE_PARAM,
-                                       sizeof(struct filter_param));
-       n->type = type;
-
-       switch (type) {
-       case F_PARAM_NAME:
-       case F_PARAM_STRING:
-               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;
-       }
-       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);
-       free(n);
-}
-
-#define plus_indent(i)         ((i) + 5)
-#define indent(f, i)           fprintf(f, "%*s", (i), "");
-#define indent_inside(f, i)    indent(f, plus_indent(i))
-
-static void dump_param(FILE *out, int i __attribute__((__unused__)), struct filter_param *n)
-{
-       fprintf(out, "param { ");
-
-       switch (n->type) {
-       case F_PARAM_NAME:
-               fprintf(out, "name: '%s'", n->val.str);
-               break;
-       case F_PARAM_STRING:
-               fprintf(out, "string: '%s'", n->val.str);
-               break;
-       case F_PARAM_NUMBER:
-               fprintf(out, "number: %llu", n->val.num);
-               break;
-       case F_PARAM_FLOAT:
-               fprintf(out, "float: %Lg", n->val.fnum);
-               break;
-       case F_PARAM_BOOLEAN:
-               fprintf(out, "bool: %s", n->val.boolean ? "true" : "false");
-               break;
-       }
-       fprintf(out, " }\n");
-}
-
-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 void dump_expr(FILE *out, int i, struct filter_expr *n)
-{
-       fprintf(out, "expr {\n");
-
-       indent_inside(out, i);
-       fprintf(out, "type: ");
-
-       switch (n->type) {
-       case F_EXPR_AND:
-               fprintf(out, "AND");
-               break;
-       case F_EXPR_OR:
-               fprintf(out, "OR");
-               break;
-       case F_EXPR_EQ:
-               fprintf(out, "EQ");
-               break;
-       case F_EXPR_NE:
-               fprintf(out, "NE");
-               break;
-       case F_EXPR_LE:
-               fprintf(out, "LE");
-               break;
-       case F_EXPR_LT:
-               fprintf(out, "LT");
-               break;
-       case F_EXPR_GE:
-               fprintf(out, "GE");
-               break;
-       case F_EXPR_GT:
-               fprintf(out, "GT");
-               break;
-       case F_EXPR_REG:
-               fprintf(out, "REG");
-               break;
-       case F_EXPR_NREG:
-               fprintf(out, "NREG");
-               break;
-       case F_EXPR_NEG:
-               fprintf(out, "NOT");
-               break;
-       }
-
-       fprintf(out, "\n");
-
-       if (n->left) {
-               indent_inside(out, i);
-               fprintf(out, "left: ");
-               filter_dump_node(out, plus_indent(i), n->left);
-       }
-
-       if (n->right) {
-               indent_inside(out, i);
-               fprintf(out, "right: ");
-               filter_dump_node(out, plus_indent(i), n->right);
-       }
-
-       indent(out, i);
-       fprintf(out, "}\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);
-               break;
-       case F_NODE_PARAM:
-               free_param((struct filter_param *) n);
-               break;
-       }
-}
-
-void filter_dump_node(FILE *out, int i, struct filter_node *n)
-{
-       if (!n)
-               return;
-
-       switch (n->type) {
-       case F_NODE_EXPR:
-               dump_expr(out, i, (struct filter_expr *) n);
-               break;
-       case F_NODE_PARAM:
-               dump_param(out, i, (struct filter_param *) n);
-               break;
-       }
-       if (i == 0)
-               fprintf(out, "\n");
-}
index 4c93a00961ff3adfe9e2054c632fd5edd0a6053d..69506ae2bb9010786f9848a56837ec5cec6f7d99 100644 (file)
@@ -13,10 +13,9 @@ void yyerror(yyscan_t *locp, struct libscols_filter *fltr, char const *msg);
 %lex-param {void *scanner}
 %parse-param {void *scanner}{struct libscols_filter *fltr}
 
-%define parse.trace
 %define parse.error verbose
 
-%header "filter-parser.h"
+/*%header "filter-parser.h"*/
 
 %code requires
 {
@@ -41,10 +40,10 @@ void yyerror(yyscan_t *locp, struct libscols_filter *fltr, char const *msg);
        struct filter_node      *param;
        struct filter_node      *expr;
 }
-%token <param_number> param_number
-%token <param_string> param_string
-%token <param_name> param_name
-%token <param_float> param_float
+%token <param_number> T_NUMBER
+%token <param_string> T_STRING
+%token <param_name> T_NAME
+%token <param_float> T_FLOAT
 %type <param> param expr
 
 %token T_OR T_AND T_EQ T_NE T_LT T_LE T_GT T_GE T_REG T_NREG T_TRUE T_FALSE T_NEG
@@ -76,10 +75,10 @@ expr:
 ;
 
 param:
-       param_number    { $$ = filter_new_param(fltr, F_PARAM_NUMBER, (void *) (&$1)); }
-       | param_float   { $$ = filter_new_param(fltr, F_PARAM_FLOAT, (void *) (&$1)); }
-       | param_name    { $$ = filter_new_param(fltr, F_PARAM_NAME, (void *) $1); }
-       | param_string  { $$ = filter_new_param(fltr, F_PARAM_STRING, (void *) $1); }
+       T_NUMBER        { $$ = filter_new_param(fltr, F_PARAM_NUMBER, (void *) (&$1)); }
+       | T_FLOAT       { $$ = filter_new_param(fltr, F_PARAM_FLOAT, (void *) (&$1)); }
+       | T_NAME        { $$ = filter_new_param(fltr, F_PARAM_NAME, (void *) $1); }
+       | T_STRING      { $$ = filter_new_param(fltr, F_PARAM_STRING, (void *) $1); }
        | T_TRUE        {
                bool x = true;
                $$ = filter_new_param(fltr, F_PARAM_BOOLEAN, (void *) &x);
@@ -94,7 +93,14 @@ param:
 
 %%
 
-void yyerror (yyscan_t *locp, struct libscols_filter *fltr, char const *msg)
+void yyerror (yyscan_t *locp __attribute__((__unused__)),
+             struct libscols_filter *fltr,
+             char const *msg)
 {
-       fprintf(stderr, "--> %s\n", msg);
+       if (msg) {
+               fltr->errmsg = strdup(msg);
+               if (!fltr->errmsg)
+                       return;
+       }
+       errno = EINVAL;
 }
index 71ce3d185e1dac4b919605e7df61a79f493923dc..c8b610e41c15dbc760cd7ba16522aaabff3453b5 100644 (file)
@@ -18,41 +18,43 @@ string      \"[^\"\n]*\"
 ")"            return ')';
 "'"            return '\'';
 
+and|AND|"&&"   return T_AND;
+or|OR|"||"     return T_OR;
+"!"|not|NOT    return T_NEG;
+
+eq|"=="                return T_EQ;
+ne|"!="                return T_NE;
+
+le|"<="                return T_LE;
+lt|"<"         return T_LT;
+
+ge|">="                return T_GE;
+gt|">"         return T_GT;
+
+"=~"           return T_REG;
+"!~"           return T_NREG;
+
 false|FALSE    return T_FALSE;
 true|TRUE      return T_TRUE;
 
 {int}+\.{int}+ {
        yylval->param_float = strtold(yytext, NULL);
-       return param_float;
+       return T_FLOAT;
 }
 
 {int}+ {
        yylval->param_number = (int64_t) strtoumax(yytext, NULL, 10);
-       return param_number;
+       return T_NUMBER;
 }
 
 {id} {
        yylval->param_name = yytext;
-       return param_name;
+       return T_NAME;
 }
 
 {string} {
        yylval->param_string = yytext;
-       return param_string;
+       return T_STRING;
 }
 
-and|AND|"&&"   return T_AND;
-or|OR|"||"     return T_OR;
-"!"|not|NOT    return T_NEG;
-
-eq|"=="                return T_EQ;
-ne|"!="                return T_NE;
 
-le|"<="                return T_LE;
-lt|"<"         return T_LT;
-
-ge|">="                return T_GE;
-gt|">"         return T_GT;
-
-"=~"           return T_REG;
-"!~"           return T_NREG;
index 74501501a6053587a75c718cc774255980e527fc..30d601a686806e248c64279bc097af26c25d2da6 100644 (file)
@@ -8,13 +8,31 @@
 #include "filter-parser.h"
 #include "filter-scanner.h"
 
-struct libscols_filter *scols_new_filter()
+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));
 
+       if (!fltr)
+               return NULL;
+       fltr->refcount = 1;
+
+       if (str && scols_filter_parse_string(fltr, str) != 0) {
+               scols_unref_filter(fltr);
+               return NULL;
+       }
+
        return fltr;
 }
 
+void scols_ref_filter(struct libscols_filter *fltr)
+{
+       if (fltr)
+               fltr->refcount++;
+}
+
 static void reset_filter(struct libscols_filter *fltr)
 {
        if (!fltr)
@@ -25,16 +43,233 @@ static void reset_filter(struct libscols_filter *fltr)
        if (fltr->src)
                fclose(fltr->src);
        fltr->src = NULL;
+
+       free(fltr->errmsg);
+       fltr->errmsg = NULL;
+}
+
+void scols_unref_filter(struct libscols_filter *fltr)
+{
+       if (fltr && --fltr->refcount <= 0) {
+               DBG(FLTR, ul_debugobj(fltr, "dealloc"));
+               reset_filter(fltr);
+               free(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)
+{
+       void *x = calloc(1, sz);
+       struct filter_node *n = (struct filter_node *) x;
+
+       if (!x)
+               return NULL;
+
+       n->type = type;
+       n->refcount = 1;
+       return n;
+}
+
+struct filter_node *filter_new_param(
+               struct libscols_filter *fltr __attribute__((__unused__)),
+               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;
+
+       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;
+       }
+       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);
+       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 "";
 }
 
-int scols_filter_parse_string(struct libscols_filter *fltr, const char *string)
+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)
+{
+       if (!n || --n->refcount > 0)
+               return;
+
+       switch (n->type) {
+       case F_NODE_EXPR:
+               free_expr((struct filter_expr *) n);
+               break;
+       case F_NODE_PARAM:
+               free_param((struct filter_param *) n);
+               break;
+       }
+}
+
+/*
+static 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)
+{
+       if (!n)
+               return;
+
+       switch (n->type) {
+       case F_NODE_EXPR:
+               dump_expr(json, (struct filter_expr *) n);
+               break;
+       case F_NODE_PARAM:
+               dump_param(json, (struct filter_param *) n);
+               break;
+       }
+}
+
+extern int yyparse(void *scanner, struct libscols_filter *fltr);
+
+int scols_filter_parse_string(struct libscols_filter *fltr, const char *str)
 {
        yyscan_t sc;
        int rc;
 
        reset_filter(fltr);
 
-       fltr->src = fmemopen((void *) string, strlen(string) + 1, "r");
+       fltr->src = fmemopen((void *) str, strlen(str) + 1, "r");
        if (!fltr->src)
                return -errno;
 
@@ -44,12 +279,28 @@ int scols_filter_parse_string(struct libscols_filter *fltr, const char *string)
        rc = yyparse(sc, fltr);
        yylex_destroy(sc);
 
+       fclose(fltr->src);
+       fltr->src = NULL;
+
        return rc;
 }
 
-/* TODO:
+int scols_dump_filter(struct libscols_filter *fltr, FILE *out)
+{
+       struct ul_jsonwrt json;
+
+       if (!fltr || !out)
+               return -EINVAL;
+
+       ul_jsonwrt_init(&json, out, 0);
+       ul_jsonwrt_root_open(&json);
 
-scols_dump_filter()
-scols_line_apply_filter()
-scols_table_apply_filter()
- */
+       filter_dump_node(&json, fltr->root);
+       ul_jsonwrt_root_close(&json);
+       return 0;
+}
+
+const char *scols_filter_get_errmsg(struct libscols_filter *fltr)
+{
+       return fltr ? fltr->errmsg : NULL;
+}
index dfd7510dcdfbcae9a1999330f58798ffc418a32c..cd5e05db6d23a7720d151a935c83854ff4a444d4 100644 (file)
@@ -28,6 +28,7 @@ UL_DEBUG_DEFINE_MASKNAMES(libsmartcols) =
        { "group", SCOLS_DEBUG_GROUP,   "lines grouping utils" },
        { "line", SCOLS_DEBUG_LINE,     "table line utils" },
        { "tab", SCOLS_DEBUG_TAB,       "table utils" },
+       { "filter", SCOLS_DEBUG_FLTR,   "lines filter" },
        { NULL, 0, NULL }
 };
 
index d58c4fd1de476bd92ecf62d5a0d4059128dce179..2262cb149cbf76dfea60ac305352173ffbee3548 100644 (file)
@@ -67,6 +67,13 @@ struct libscols_table;
  */
 struct libscols_column;
 
+/**
+ * libscols_filter:
+ *
+ * A filter - defines the filtering
+ */
+struct libscols_filter;
+
 /* iter.c */
 enum {
 
@@ -358,6 +365,15 @@ extern int scols_table_print_range_to_string(      struct libscols_table *tb,
 int scols_line_link_group(struct libscols_line *ln, struct libscols_line *member, int id);
 int scols_table_group_lines(struct libscols_table *tb, struct libscols_line *ln,
                             struct libscols_line *member, int id);
+
+/* filter.c */
+extern int scols_filter_parse_string(struct libscols_filter *fltr, const char *str);
+extern struct libscols_filter *scols_new_filter(const char *str);
+extern void scols_ref_filter(struct libscols_filter *fltr);
+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);
+
 #ifdef __cplusplus
 }
 #endif
index 28811691172aaf80b283f5ebbe820d1a5f5d0cae..4fb97f43e7c4fe367dfd65afe62abbd129086274 100644 (file)
@@ -221,4 +221,9 @@ SMARTCOLS_2.40 {
        scols_cell_get_datasiz;
        scols_wrapzero_nextchunk;
        scols_column_get_wrap_data;
+       scols_dump_filter;
+       scols_filter_parse_string;
+       scols_new_filter;
+       scols_unref_filter;
+       scols_filter_get_errmsg;
 } SMARTCOLS_2.39;
index 1b476f8599deecb849882f53ec31a00efd1b19fc..86c07ea40e783f1ad4af6ddbe908a6a68f727242 100644 (file)
@@ -34,6 +34,7 @@
 #define SCOLS_DEBUG_COL                (1 << 5)
 #define SCOLS_DEBUG_BUFF       (1 << 6)
 #define SCOLS_DEBUG_GROUP      (1 << 7)
+#define SCOLS_DEBUG_FLTR       (1 << 8)
 #define SCOLS_DEBUG_ALL                0xFFFF
 
 UL_DEBUG_DECLARE_MASK(libsmartcols);
@@ -542,14 +543,13 @@ struct filter_expr {
 };
 
 struct libscols_filter {
+       int refcount;
+       char *errmsg;
        struct filter_node *root;
        FILE *src;
 };
 
-void filter_unref_node(struct filter_node *n);
-void filter_dump_node(FILE *out, int i, struct filter_node *n);
-
-/* reuiqred by parser */
+/* required by parser */
 struct filter_node *filter_new_param(struct libscols_filter *filter,
                                  enum filter_ptype type,
                                 void *data);